id_list_t *ids;
enum PrivateKeyKind kind;
union {
- chunk_t preshared_secret;
- xauth_t xauth_secret;
+ chunk_t preshared_secret;
+ xauth_t xauth_secret;
private_key_t *private_key;
- smartcard_t *smartcard;
+ smartcard_t *smartcard;
} u;
secret_t *next;
};
-static public_key_t* get_public_key(const cert_t cert)
-{
- switch (cert.type)
- {
- case CERT_PGP:
- /*
- e = cert.u.pgp->publicExponent;
- n = cert.u.pgp->modulus;
- init_RSA_public_key(&pk->public_key, e, n);
- */
- return NULL;
- break;
- case CERT_X509_SIGNATURE:
- return cert.u.x509->public_key;
- break;
- default:
- return NULL;
- }
-}
-
/*
* free a public key struct
*/
enum PrivateKeyKind kind, bool asym)
{
enum { /* bits */
- match_default = 01,
- match_him = 02,
- match_me = 04
+ match_default = 0x01,
+ match_him = 0x02,
+ match_me = 0x04
};
unsigned int best_match = 0;
/* is there a certificate assigned to this connection? */
if (kind == PPK_PUBKEY && c->spd.this.cert.type != CERT_NONE)
{
- public_key_t *pub_key = get_public_key(c->spd.this.cert);
+ public_key_t *pub_key = cert_get_public_key(c->spd.this.cert);
for (s = secrets; s != NULL; s = s->next)
{
for (i = s->ids; i != NULL; i = i->next)
{
if (same_id(my_id, &i->id))
+ {
match |= match_me;
-
+ }
if (same_id(his_id, &i->id))
+ {
match |= match_him;
+ }
}
/* If our end matched the only id in the list,
* there are other ids in the list.
*/
if (!asym)
+ {
break;
+ }
/* FALLTHROUGH */
case match_default: /* default all */
case match_me | match_default: /* default peer */
{
secret_t *s;
bool has_key = FALSE;
- public_key_t *pub_key = get_public_key(cert);
+ public_key_t *pub_key = cert_get_public_key(cert);
for (s = secrets; s != NULL; s = s->next)
{
return ugh;
}
-const char *rsa_private_keywords[] = {
+typedef enum rsa_private_key_part_t rsa_private_key_part_t;
+
+enum rsa_private_key_part_t {
+ RSA_PART_MODULUS = 0,
+ RSA_PART_PUBLIC_EXPONENT = 1,
+ RSA_PART_PRIVATE_EXPONENT = 2,
+ RSA_PART_PRIME1 = 3,
+ RSA_PART_PRIME2 = 4,
+ RSA_PART_EXPONENT1 = 5,
+ RSA_PART_EXPONENT2 = 6,
+ RSA_PART_COEFFICIENT = 7
+};
+
+const char *rsa_private_key_part_names[] = {
"Modulus",
"PublicExponent",
"PrivateExponent",
*/
static err_t process_rsa_secret(private_key_t **key)
{
- chunk_t asn1_chunks[countof(rsa_private_keywords)];
+ chunk_t asn1_chunk[countof(rsa_private_key_part_names)];
chunk_t pkcs1_chunk;
u_char buf[RSA_MAX_ENCODING_BYTES]; /* limit on size of binary representation of key */
- err_t ugh;
- int i, j;
+ rsa_private_key_part_t part, p;
size_t sz, len = 0;
+ err_t ugh;
- for (i = 0; i < countof(rsa_private_keywords); i++)
+ for (part = RSA_PART_MODULUS; part <= RSA_PART_COEFFICIENT; part++)
{
- chunk_t rsa_private_key_chunk;
- const char *keyword = rsa_private_keywords[i];
+ chunk_t rsa_private_key_part;
+ const char *keyword = rsa_private_key_part_names[part];
if (!shift())
{
if (ugh)
{
ugh = builddiag("RSA data malformed (%s): %s", ugh, tok);
- i++;
+ part++;
goto end;
}
- rsa_private_key_chunk = chunk_create(buf, sz);
- asn1_chunks[i] = asn1_integer("c", rsa_private_key_chunk);
- len += asn1_chunks[i].len;
+ rsa_private_key_part = chunk_create(buf, sz);
+ asn1_chunk[part] = asn1_integer("c", rsa_private_key_part);
+ len += asn1_chunk[part].len;
}
/* We require an (indented) '}' and the end of the record.
pkcs1_chunk = asn1_wrap(ASN1_SEQUENCE, "ccccccccc",
ASN1_INTEGER_0,
- asn1_chunks[0],
- asn1_chunks[1],
- asn1_chunks[2],
- asn1_chunks[3],
- asn1_chunks[4],
- asn1_chunks[5],
- asn1_chunks[6],
- asn1_chunks[7]);
+ asn1_chunk[RSA_PART_MODULUS],
+ asn1_chunk[RSA_PART_PUBLIC_EXPONENT],
+ asn1_chunk[RSA_PART_PRIVATE_EXPONENT],
+ asn1_chunk[RSA_PART_PRIME1],
+ asn1_chunk[RSA_PART_PRIME2],
+ asn1_chunk[RSA_PART_EXPONENT1],
+ asn1_chunk[RSA_PART_EXPONENT2],
+ asn1_chunk[RSA_PART_COEFFICIENT]);
*key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
BUILD_BLOB_ASN1_DER, pkcs1_chunk,
}
end:
- for (j = 0 ; j < i; j++)
+ /* clean up and return */
+ for (p = RSA_PART_MODULUS ; p < part; p++)
{
- free(asn1_chunks[j].ptr);
+ free(asn1_chunk[p].ptr);
}
return ugh;
}
{
(void)flushline(NULL); /* silently ditch leftovers, if any */
if (flp->bdry == B_file)
+ {
break;
-
+ }
flp->bdry = B_none; /* eat the Record Boundary */
(void)shift(); /* get real first token */
* will be rediscovered and reported later.
*/
if (pl > sizeof(fn))
+ {
pl = sizeof(fn);
+ }
memcpy(fn, flp->filename, pl);
p += pl;
}
pubkey_list_t *nxt = p->next;
if (p->key != NULL)
+ {
unreference_key(&p->key);
+ }
free(p);
return nxt;
}
void free_public_keys(pubkey_list_t **keys)
{
while (*keys != NULL)
+ {
*keys = free_public_keyentry(*keys);
+ }
}
/* root of chained public key list */
pubkey_list_t **pp = keys;
while (*pp != NULL)
+ {
pp = &(*pp)->next;
+ }
*pp = pubkeys;
pubkeys = *keys;
*keys = NULL;
char b[BUF_LEN];
if (pk == NULL)
+ {
return;
+ }
/* print stuff */
DBG(DBG_CONTROLMORE,
passert(pk->refcnt != 0);
pk->refcnt--;
if (pk->refcnt == 0)
+ {
free_public_key(pk);
+ }
}
bool add_public_key(const struct id *id, enum dns_auth_level dns_auth_level,
pk->public_key = cert->public_key->get_ref(cert->public_key);
pk->id.kind = ID_KEY_ID;
pk->id.name = cert->fingerprint->get_encoding(cert->fingerprint);
- pk->id.name = chunk_clone(pk->id.name);
pk->dns_auth_level = dns_auth_level;
pk->until_time = until;
pk_type = pk->public_key->get_type(pk->public_key);
{
/* remove p from list and free memory */
*pp = free_public_keyentry(p);
- loglog(RC_LOG_SERIOUS,
- "invalid RSA public key deleted");
+ loglog(RC_LOG_SERIOUS, "invalid public key deleted");
}
else
{
#include "whack.h"
#include "keys.h"
-/*
- * chained list of OpenPGP end certificates
+/**
+ * Chained list of OpenPGP end certificates
*/
static pgpcert_t *pgpcerts = NULL;
-/*
+/**
* Size of PGP Key ID
*/
#define PGP_KEYID_SIZE 8
-const pgpcert_t empty_pgpcert = {
- NULL , /* *next */
+const pgpcert_t pgpcert_empty = {
+ NULL , /* next */
+ 0 , /* version */
0 , /* installed */
0 , /* count */
{ NULL, 0 }, /* certificate */
};
-/*
- * extracts the length of a PGP packet
+/**
+ * Extracts the length of a PGP packet
*/
static size_t pgp_old_packet_length(chunk_t *blob)
{
return pgp_length(blob, (len_type == 0)? 1: len_type << 1);
}
-/*
- * extracts PGP packet version (V3 or V4)
+/**
+ * Extracts PGP packet version (V3 or V4)
*/
static u_char pgp_version(chunk_t *blob)
{
return version;
}
-/*
- * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 2440
+/**
+ * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 2440
*/
-static bool parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
+static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
{
+ time_t created;
+ chunk_t keyid;
+ u_char sig_type;
u_char version = pgp_version(packet);
- public_key_t *key;
- if (version < 3 || version > 4)
+ /* we parse only V3 signature packets */
+ if (version != 3)
+ {
+ return TRUE;
+ }
+
+ /* size byte must have the value 5 */
+ if (pgp_length(packet, 1) != 5)
{
- plog("PGP packet version V%d not supported", version);
+ plog(" size must be 5");
+ return FALSE;
+ }
+
+ /* signature type - 1 byte */
+ sig_type = (u_char)pgp_length(packet, 1);
+ DBG(DBG_PARSING,
+ DBG_log("L3 - signature type: 0x%2x", sig_type)
+ )
+
+ /* creation date - 4 bytes */
+ created = (time_t)pgp_length(packet, 4);
+ DBG(DBG_PARSING,
+ DBG_log("L3 - created:");
+ DBG_log(" %T", &cert->created, TRUE)
+ )
+
+ /* key ID of signer - 8 bytes */
+ keyid.ptr = packet->ptr;
+ keyid.len = PGP_KEYID_SIZE;
+ DBG_cond_dump_chunk(DBG_PARSING, "L3 - key ID of signer", keyid);
+
+ return TRUE;
+}
+
+/**
+ * Parses the version and validity of an OpenPGP public key packet
+ */
+static bool parse_pgp_pubkey_version_validity(chunk_t *packet, pgpcert_t *cert)
+{
+ cert->version = pgp_version(packet);
+
+ if (cert->version < 3 || cert->version > 4)
+ {
+ plog("OpenPGP packet version V%d not supported", cert->version);
return FALSE;
}
DBG_log(" %T", &cert->created, TRUE)
)
- if (version == 3)
+ if (cert->version == 3)
{
/* validity in days - 2 bytes */
cert->until = (time_t)pgp_length(packet, 2);
DBG_log(" %T", &cert->until, TRUE);
)
}
+ return TRUE;
+}
+
+/**
+ * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 4880
+ */
+static bool parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
+{
+ pgp_pubkey_alg_t pubkey_alg;
+ public_key_t *key;
+
+ if (!parse_pgp_pubkey_version_validity(packet, cert))
+ {
+ return FALSE;
+ }
/* public key algorithm - 1 byte */
+ pubkey_alg = pgp_length(packet, 1);
DBG(DBG_PARSING,
- DBG_log("L3 - public key algorithm:")
+ DBG_log("L3 - public key algorithm:");
+ DBG_log(" %N", pgp_pubkey_alg_names, pubkey_alg)
)
-
- switch (pgp_length(packet, 1))
+
+ switch (pubkey_alg)
{
- case PGP_PUBKEY_ALG_RSA:
- case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
- DBG(DBG_PARSING,
- DBG_log(" RSA")
- )
- key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
- BUILD_BLOB_PGP, *packet,
- BUILD_END);
- if (key == NULL)
- {
- return FALSE;
- }
- cert->public_key = key;
+ case PGP_PUBKEY_ALG_RSA:
+ case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ BUILD_BLOB_PGP, *packet,
+ BUILD_END);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ cert->public_key = key;
- if (version == 3)
- {
- cert->fingerprint = key->get_id(key, ID_KEY_ID);
- if (cert->fingerprint == NULL)
+ if (cert->version == 3)
{
+ cert->fingerprint = key->get_id(key, ID_KEY_ID);
+ if (cert->fingerprint == NULL)
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ plog(" computation of V4 key ID not implemented yet");
return FALSE;
}
- }
- else
- {
- plog(" computation of V4 key ID not implemented yet");
- }
- break;
- case PGP_PUBKEY_ALG_DSA:
- DBG(DBG_PARSING,
- DBG_log(" DSA")
- )
- plog(" DSA public keys not supported");
- return FALSE;
- default:
- DBG(DBG_PARSING,
- DBG_log(" other")
- )
- plog(" exotic not RSA public keys not supported");
- return FALSE;
+ break;
+ default:
+ plog(" non RSA public keys not supported");
+ return FALSE;
}
return TRUE;
}
/*
- * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 2440
+ * Parse OpenPGP secret key packet defined in section 5.5.3 of RFC 4880
*/
-static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
+static bool parse_pgp_secretkey_packet(chunk_t *packet, private_key_t **key)
{
- time_t created;
- chunk_t keyid;
- u_char sig_type;
- u_char version = pgp_version(packet);
+ pgp_pubkey_alg_t pubkey_alg;
+ pgpcert_t cert = pgpcert_empty;
- /* we parse only V3 signature packets */
- if (version != 3)
- return TRUE;
-
- /* size byte must have the value 5 */
- if (pgp_length(packet, 1) != 5)
+ if (!parse_pgp_pubkey_version_validity(packet, &cert))
{
- plog(" size must be 5");
return FALSE;
}
- /* signature type - 1 byte */
- sig_type = (u_char)pgp_length(packet, 1);
- DBG(DBG_PARSING,
- DBG_log("L3 - signature type: 0x%2x", sig_type)
- )
-
- /* creation date - 4 bytes */
- created = (time_t)pgp_length(packet, 4);
+ /* public key algorithm - 1 byte */
+ pubkey_alg = pgp_length(packet, 1);
DBG(DBG_PARSING,
- DBG_log("L3 - created:");
- DBG_log(" %T", &cert->created, TRUE)
+ DBG_log("L3 - public key algorithm:");
+ DBG_log(" %N", pgp_pubkey_alg_names, pubkey_alg)
)
-
- /* key ID of signer - 8 bytes */
- keyid.ptr = packet->ptr;
- keyid.len = PGP_KEYID_SIZE;
- DBG_cond_dump_chunk(DBG_PARSING, "L3 - key ID of signer", keyid);
-
- return TRUE;
+
+ switch (pubkey_alg)
+ {
+ case PGP_PUBKEY_ALG_RSA:
+ case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
+ *key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_PGP, *packet,
+ BUILD_END);
+ break;
+ default:
+ plog(" non RSA private keys not supported");
+ return FALSE;
+ }
+ return (*key != NULL);
}
bool parse_pgp(chunk_t blob, pgpcert_t *cert, private_key_t **key)
/* parse a PGP certificate */
switch (packet_type)
{
- case PGP_PKT_PUBLIC_KEY:
- if (!parse_pgp_pubkey_packet(&packet, cert))
- {
- return FALSE;
- }
- break;
- case PGP_PKT_SIGNATURE:
- if (!parse_pgp_signature_packet(&packet, cert))
- {
- return FALSE;
- }
- break;
- case PGP_PKT_USER_ID:
- DBG(DBG_PARSING,
- DBG_log("L3 - user ID:");
- DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
- )
- break;
- default:
- break;
+ case PGP_PKT_PUBLIC_KEY:
+ if (!parse_pgp_pubkey_packet(&packet, cert))
+ {
+ return FALSE;
+ }
+ break;
+ case PGP_PKT_SIGNATURE:
+ if (!parse_pgp_signature_packet(&packet, cert))
+ {
+ return FALSE;
+ }
+ break;
+ case PGP_PKT_USER_ID:
+ DBG(DBG_PARSING,
+ DBG_log("L3 - user ID:");
+ DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
+ )
+ break;
+ default:
+ break;
}
}
else
/* parse a PGP private key file */
switch (packet_type)
{
- case PGP_PKT_SECRET_KEY:
- *key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- BUILD_BLOB_PGP, packet,
- BUILD_END);
- break;
- default:
- break;
- }
- if (*key == NULL)
- {
- return FALSE;
+ case PGP_PKT_SECRET_KEY:
+ if (!parse_pgp_secretkey_packet(&packet, key))
+ {
+ return FALSE;
+ }
+ break;
+ case PGP_PKT_USER_ID:
+ DBG(DBG_PARSING,
+ DBG_log("L3 - user ID:");
+ DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
+ )
+ break;
+ default:
+ break;
}
}
return TRUE;
}
-/*
- * compare two OpenPGP certificates
+/**
+ * Compare two OpenPGP certificates
*/
static bool same_pgpcert(pgpcert_t *a, pgpcert_t *b)
{
memeq(a->certificate.ptr, b->certificate.ptr, b->certificate.len);
}
-/*
- * for each link pointing to the certificate increase the count by one
+/**
+ * For each link pointing to the certificate increase the count by one
*/
void share_pgpcert(pgpcert_t *cert)
{
}
}
-/*
- * select the OpenPGP keyid as ID
+/**
+ * Select the OpenPGP keyid as ID
*/
void select_pgpcert_id(pgpcert_t *cert, struct id *end_id)
{
end_id->kind = ID_KEY_ID;
end_id->name = cert->fingerprint->get_encoding(cert->fingerprint);
- end_id->name = chunk_clone(end_id->name);
}
-/*
- * add an OpenPGP user/host certificate to the chained list
+/**
+ * Add an OpenPGP user/host certificate to the chained list
*/
pgpcert_t* add_pgpcert(pgpcert_t *cert)
{
return cert;
}
-/* release of a certificate decreases the count by one
- " the certificate is freed when the counter reaches zero
+/**
+ * Release of a certificate decreases the count by one.
+ * The certificate is freed when the counter reaches zero
*/
void release_pgpcert(pgpcert_t *cert)
{
}
}
-/*
- * free a PGP certificate
+/**
+ * Free a PGP certificate
*/
void free_pgpcert(pgpcert_t *cert)
{
}
}
-/*
- * list all PGP end certificates in a chained list
+/**
+ * List all PGP end certificates in a chained list
*/
void list_pgp_end_certs(bool utc)
{
c.u.pgp = cert;
whack_log(RC_COMMENT, "%T, count: %d", &cert->installed, utc, cert->count);
- whack_log(RC_COMMENT, " fingerprint: %Y", cert->fingerprint);
+ whack_log(RC_COMMENT, " digest: %Y", cert->fingerprint);
+ whack_log(RC_COMMENT, " created: %T", &cert->created, utc);
+ whack_log(RC_COMMENT, " until: %T %s", &cert->until, utc,
+ check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE));
whack_log(RC_COMMENT, " pubkey: %N %4d bits%s",
key_type_names, key->get_type(key),
key->get_keysize(key) * BITS_PER_BYTE,
has_private_key(c)? ", has private key" : "");
whack_log(RC_COMMENT, " keyid: %Y",
key->get_id(key, ID_PUBKEY_INFO_SHA1));
- whack_log(RC_COMMENT, " created: %T", &cert->created, utc);
- whack_log(RC_COMMENT, " until: %T %s", &cert->until, utc,
- check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE));
cert = cert->next;
}
}