1 /* Support of OpenPGP certificates
2 * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: pgp.c,v 1.7 2006/01/04 21:00:43 as Exp $
22 #include <freeswan/ipsec_policy.h>
24 #include "constants.h"
37 * chained list of OpenPGP end certificates
39 static pgpcert_t
*pgpcerts
= NULL
;
42 * OpenPGP packet tags defined in section 4.3 of RFC 2440
44 #define PGP_PKT_RESERVED 0
45 #define PGP_PKT_PUBKEY_ENC_SESSION_KEY 1
46 #define PGP_PKT_SIGNATURE 2
47 #define PGP_PKT_SYMKEY_ENC_SESSION_KEY 3
48 #define PGP_PKT_ONE_PASS_SIGNATURE_PKT 4
49 #define PGP_PKT_SECRET_KEY 5
50 #define PGP_PKT_PUBLIC_KEY 6
51 #define PGP_PKT_SECRET_SUBKEY 7
52 #define PGP_PKT_COMPRESSED_DATA 8
53 #define PGP_PKT_SYMKEY_ENC_DATA 9
54 #define PGP_PKT_MARKER 10
55 #define PGP_PKT_LITERAL_DATA 11
56 #define PGP_PKT_TRUST 12
57 #define PGP_PKT_USER_ID 13
58 #define PGP_PKT_PUBLIC_SUBKEY 14
59 #define PGP_PKT_ROOF 15
61 static const char *const pgp_packet_type_name
[] = {
63 "Public-Key Encrypted Session Key Packet",
65 "Symmetric-Key Encrypted Session Key Packet",
66 "One-Pass Signature Packet",
69 "Secret Subkey Packet",
70 "Compressed Data Packet",
71 "Symmetrically Encrypted Data Packet",
73 "Literal Data Packet",
76 "Public Subkey Packet"
80 * OpenPGP public key algorithms defined in section 9.1 of RFC 2440
82 #define PGP_PUBKEY_ALG_RSA 1
83 #define PGP_PUBKEY_ALG_RSA_ENC_ONLY 2
84 #define PGP_PUBKEY_ALG_RSA_SIGN_ONLY 3
85 #define PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY 16
86 #define PGP_PUBKEY_ALG_DSA 17
87 #define PGP_PUBKEY_ALG_ECC 18
88 #define PGP_PUBKEY_ALG_ECDSA 19
89 #define PGP_PUBKEY_ALG_ELGAMAL 20
92 * OpenPGP symmetric key algorithms defined in section 9.2 of RFC 2440
94 #define PGP_SYM_ALG_PLAIN 0
95 #define PGP_SYM_ALG_IDEA 1
96 #define PGP_SYM_ALG_3DES 2
97 #define PGP_SYM_ALG_CAST5 3
98 #define PGP_SYM_ALG_BLOWFISH 4
99 #define PGP_SYM_ALG_SAFER 5
100 #define PGP_SYM_ALG_DES 6
101 #define PGP_SYM_ALG_AES 7
102 #define PGP_SYM_ALG_AES_192 8
103 #define PGP_SYM_ALG_AES_256 9
104 #define PGP_SYM_ALG_TWOFISH 10
105 #define PGP_SYM_ALG_ROOF 11
107 static const char *const pgp_sym_alg_name
[] = {
124 #define PGP_KEYID_SIZE 8
126 const pgpcert_t empty_pgpcert
= {
130 { NULL
, 0 }, /* certificate */
133 0 , /* pubkeyAlgorithm */
134 { NULL
, 0 }, /* modulus */
135 { NULL
, 0 }, /* publicExponent */
140 pgp_size(chunk_t
*blob
, int len
)
146 size
= 256*size
+ *blob
->ptr
++;
151 * extracts the length of a PGP packet
154 pgp_old_packet_length(chunk_t
*blob
)
156 /* bits 0 and 1 define the packet length type */
157 int len_type
= 0x03 & *blob
->ptr
++;
161 /* len_type: 0 -> 1 byte, 1 -> 2 bytes, 2 -> 4 bytes */
162 return pgp_size(blob
, (len_type
== 0)? 1: len_type
<< 1);
166 * extracts PGP packet version (V3 or V4)
169 pgp_version(chunk_t
*blob
)
171 u_char version
= *blob
->ptr
++;
174 DBG_log("L3 - version:");
175 DBG_log(" V%d", version
)
181 * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 2440
184 parse_pgp_pubkey_packet(chunk_t
*packet
, pgpcert_t
*cert
)
186 u_char version
= pgp_version(packet
);
188 if (version
< 3 || version
> 4)
190 plog("PGP packet version V%d not supported", version
);
194 /* creation date - 4 bytes */
195 cert
->created
= (time_t)pgp_size(packet
, 4);
197 DBG_log("L3 - created:");
198 DBG_log(" %s", timetoa(&cert
->created
, TRUE
))
203 /* validity in days - 2 bytes */
204 cert
->until
= (time_t)pgp_size(packet
, 2);
206 /* validity of 0 days means that the key never expires */
208 cert
->until
= cert
->created
+ 24*3600*cert
->until
;
211 DBG_log("L3 - until:");
212 DBG_log(" %s", timetoa(&cert
->until
, TRUE
));
216 /* public key algorithm - 1 byte */
218 DBG_log("L3 - public key algorithm:")
221 switch (pgp_size(packet
, 1))
223 case PGP_PUBKEY_ALG_RSA
:
224 case PGP_PUBKEY_ALG_RSA_SIGN_ONLY
:
225 cert
->pubkeyAlg
= PUBKEY_ALG_RSA
;
230 cert
->modulus
.len
= (pgp_size(packet
, 2)+7) / BITS_PER_BYTE
;
231 cert
->modulus
.ptr
= packet
->ptr
;
232 packet
->ptr
+= cert
->modulus
.len
;
233 packet
->len
-= cert
->modulus
.len
;
235 DBG_log("L3 - modulus:")
237 DBG_cond_dump_chunk(DBG_RAW
, "", cert
->modulus
);
239 /* public exponent e */
240 cert
->publicExponent
.len
= (pgp_size(packet
, 2)+7) / BITS_PER_BYTE
;
241 cert
->publicExponent
.ptr
= packet
->ptr
;
242 packet
->ptr
+= cert
->publicExponent
.len
;
243 packet
->len
-= cert
->publicExponent
.len
;
245 DBG_log("L3 - public exponent:")
247 DBG_cond_dump_chunk(DBG_RAW
, "", cert
->publicExponent
);
251 /* a V3 fingerprint is the MD5 hash of modulus and public exponent */
254 MD5Update(&context
, cert
->modulus
.ptr
, cert
->modulus
.len
);
255 MD5Update(&context
, cert
->publicExponent
.ptr
, cert
->publicExponent
.len
);
256 MD5Final(cert
->fingerprint
, &context
);
260 plog(" computation of V4 key ID not implemented yet");
263 case PGP_PUBKEY_ALG_DSA
:
264 cert
->pubkeyAlg
= PUBKEY_ALG_DSA
;
268 plog(" DSA public keys not supported");
275 plog(" exotic not RSA public keys not supported");
282 * Parse OpenPGP secret key packet defined in section 5.5.3 of RFC 2440
285 parse_pgp_secretkey_packet(chunk_t
*packet
, RSA_private_key_t
*key
)
288 pgpcert_t cert
= empty_pgpcert
;
290 if (!parse_pgp_pubkey_packet(packet
, &cert
))
293 init_RSA_public_key((RSA_public_key_t
*)key
, cert
.publicExponent
296 /* string-to-key usage */
297 s2k
= pgp_size(packet
, 1);
300 DBG_log("L3 - string-to-key: %d", s2k
)
305 plog(" string-to-key specifiers not supported");
309 if (s2k
>= PGP_SYM_ALG_ROOF
)
311 plog(" undefined symmetric key algorithm");
315 /* a known symmetric key algorithm is specified*/
317 DBG_log(" %s", pgp_sym_alg_name
[s2k
])
320 /* private key is unencrypted */
321 if (s2k
== PGP_SYM_ALG_PLAIN
)
323 for (i
= 2; i
< RSA_PRIVATE_FIELD_ELEMENTS
; i
++)
325 mpz_t u
; /* auxiliary variable */
327 /* compute offset to private key component i*/
328 MP_INT
*n
= (MP_INT
*)((char *)key
+ RSA_private_field
[i
].offset
);
336 size_t len
= (pgp_size(packet
, 2)+7) / BITS_PER_BYTE
;
338 n_to_mpz(n
, packet
->ptr
, len
);
340 DBG_log("L3 - %s:", RSA_private_field
[i
].name
)
342 DBG_cond_dump(DBG_PRIVATE
, "", packet
->ptr
, len
);
347 case 5: /* dP = d mod (p-1) */
349 mpz_sub_ui(u
, &key
->p
, 1);
350 mpz_mod(n
, &key
->d
, u
);
353 case 6: /* dQ = d mod (q-1) */
355 mpz_sub_ui(u
, &key
->q
, 1);
356 mpz_mod(n
, &key
->d
, u
);
359 case 7: /* qInv = (q^-1) mod p */
360 mpz_invert(n
, &key
->q
, &key
->p
);
361 if (mpz_cmp_ui(n
, 0) < 0)
362 mpz_add(n
, n
, &key
->p
);
363 passert(mpz_cmp(n
, &key
->p
) < 0);
370 plog(" %s encryption not supported", pgp_sym_alg_name
[s2k
]);
375 * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 2440
378 parse_pgp_signature_packet(chunk_t
*packet
, pgpcert_t
*cert
)
383 u_char version
= pgp_version(packet
);
385 /* we parse only V3 signature packets */
389 /* size byte must have the value 5 */
390 if (pgp_size(packet
, 1) != 5)
392 plog(" size must be 5");
396 /* signature type - 1 byte */
397 sig_type
= (u_char
)pgp_size(packet
, 1);
399 DBG_log("L3 - signature type: 0x%2x", sig_type
)
402 /* creation date - 4 bytes */
403 created
= (time_t)pgp_size(packet
, 4);
405 DBG_log("L3 - created:");
406 DBG_log(" %s", timetoa(&cert
->created
, TRUE
))
409 /* key ID of signer - 8 bytes */
410 keyid
.ptr
= packet
->ptr
;
411 keyid
.len
= PGP_KEYID_SIZE
;
412 DBG_cond_dump_chunk(DBG_PARSING
, "L3 - key ID of signer", keyid
);
418 parse_pgp(chunk_t blob
, pgpcert_t
*cert
, RSA_private_key_t
*key
)
421 DBG_log("L0 - PGP file:")
423 DBG_cond_dump_chunk(DBG_RAW
, "", blob
);
427 /* parse a PGP certificate file */
428 cert
->certificate
= blob
;
429 time(&cert
->installed
);
431 else if (key
== NULL
)
433 /* should not occur, nothing to parse */
439 chunk_t packet
= empty_chunk
;
440 u_char packet_tag
= *blob
.ptr
;
443 DBG_log("L1 - PGP packet: tag= 0x%2x", packet_tag
)
446 /* bit 7 must be set */
447 if (!(packet_tag
& 0x80))
449 plog(" incorrect Packet Tag");
453 /* bit 6 set defines new packet format */
454 if (packet_tag
& 0x40)
456 plog(" new PGP packet format not supported");
461 int packet_type
= (packet_tag
& 0x3C) >> 2;
463 packet
.len
= pgp_old_packet_length(&blob
);
464 packet
.ptr
= blob
.ptr
;
465 blob
.ptr
+= packet
.len
;
466 blob
.len
-= packet
.len
;
468 DBG_log(" %s (%d), old format, %d bytes",
469 (packet_type
< PGP_PKT_ROOF
) ?
470 pgp_packet_type_name
[packet_type
] :
471 "Undefined Packet Type", packet_type
, (int)packet
.len
);
472 DBG_log("L2 - body:")
474 DBG_cond_dump_chunk(DBG_RAW
, "", packet
);
478 /* parse a PGP certificate */
481 case PGP_PKT_PUBLIC_KEY
:
482 if (!parse_pgp_pubkey_packet(&packet
, cert
))
485 case PGP_PKT_SIGNATURE
:
486 if (!parse_pgp_signature_packet(&packet
, cert
))
489 case PGP_PKT_USER_ID
:
491 DBG_log("L3 - user ID:");
492 DBG_log(" '%.*s'", (int)packet
.len
, packet
.ptr
)
501 /* parse a PGP private key file */
504 case PGP_PKT_SECRET_KEY
:
505 if (!parse_pgp_secretkey_packet(&packet
, key
))
518 * compare two OpenPGP certificates
521 same_pgpcert(pgpcert_t
*a
, pgpcert_t
*b
)
523 return a
->certificate
.len
== b
->certificate
.len
&&
524 memcmp(a
->certificate
.ptr
, b
->certificate
.ptr
, b
->certificate
.len
) == 0;
528 * for each link pointing to the certificate increase the count by one
531 share_pgpcert(pgpcert_t
*cert
)
538 * select the OpenPGP keyid as ID
541 select_pgpcert_id(pgpcert_t
*cert
, struct id
*end_id
)
543 end_id
->kind
= ID_KEY_ID
;
544 end_id
->name
.len
= PGP_FINGERPRINT_SIZE
;
545 end_id
->name
.ptr
= cert
->fingerprint
;
546 end_id
->name
.ptr
= temporary_cyclic_buffer();
547 memcpy(end_id
->name
.ptr
, cert
->fingerprint
, PGP_FINGERPRINT_SIZE
);
551 * add an OpenPGP user/host certificate to the chained list
554 add_pgpcert(pgpcert_t
*cert
)
556 pgpcert_t
*c
= pgpcerts
;
560 if (same_pgpcert(c
, cert
)) /* already in chain, free cert */
568 /* insert new cert at the root of the chain */
569 cert
->next
= pgpcerts
;
571 DBG(DBG_CONTROL
| DBG_PARSING
,
572 DBG_log(" pgp cert inserted")
577 /* release of a certificate decreases the count by one
578 " the certificate is freed when the counter reaches zero
581 release_pgpcert(pgpcert_t
*cert
)
583 if (cert
!= NULL
&& --cert
->count
== 0)
585 pgpcert_t
**pp
= &pgpcerts
;
594 * free a PGP certificate
597 free_pgpcert(pgpcert_t
*cert
)
601 if (cert
->certificate
.ptr
!= NULL
)
602 pfree(cert
->certificate
.ptr
);
608 * list all PGP end certificates in a chained list
611 list_pgp_end_certs(bool utc
)
613 pgpcert_t
*cert
= pgpcerts
;
616 /* determine the current time */
621 whack_log(RC_COMMENT
, " ");
622 whack_log(RC_COMMENT
, "List of PGP End certificates:");
623 whack_log(RC_COMMENT
, " ");
635 whack_log(RC_COMMENT
, "%s, count: %d", timetoa(&cert
->installed
, utc
), cert
->count
);
636 datatot(cert
->fingerprint
, PGP_FINGERPRINT_SIZE
, 'x', buf
, BUF_LEN
);
637 whack_log(RC_COMMENT
, " fingerprint: %s", buf
);
638 form_keyid(cert
->publicExponent
, cert
->modulus
, buf
, &keysize
);
639 whack_log(RC_COMMENT
, " pubkey: %4d RSA Key %s%s", 8*keysize
, buf
,
640 (has_private_key(c
))? ", has private key" : "");
641 whack_log(RC_COMMENT
, " created: %s", timetoa(&cert
->created
, utc
));
642 whack_log(RC_COMMENT
, " until: %s %s", timetoa(&cert
->until
, utc
),
643 check_expiry(cert
->until
, CA_CERT_WARNING_INTERVAL
, TRUE
));