fixed OpenPGP parsing

This commit is contained in:
Andreas Steffen 2009-06-06 13:13:11 +02:00 committed by Martin Willi
parent ca062e48ee
commit d17a120598
9 changed files with 311 additions and 231 deletions

View File

@ -23,6 +23,7 @@
#define PGP_H_
typedef enum pgp_packet_tag_t pgp_packet_tag_t;
typedef enum pgp_pubkey_alg_t pgp_pubkey_alg_t;
typedef enum pgp_sym_alg_t pgp_sym_alg_t;
#include <chunk.h>

View File

@ -815,7 +815,6 @@ static gmp_rsa_private_key_t *load_pgp(chunk_t blob)
{
mpz_t u;
int objectID;
pgp_sym_alg_t s2k;
chunk_t packet = blob;
private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
@ -828,27 +827,33 @@ static gmp_rsa_private_key_t *load_pgp(chunk_t blob)
mpz_init(this->exp2);
mpz_init(this->coeff);
/* string-to-key usage */
s2k = pgp_length(&packet, 1);
DBG2("L3 - string-to-key: %d", s2k);
if (s2k == 255 || s2k == 254)
{
DBG1("string-to-key specifiers not supported");
goto end;
}
DBG2(" %N", pgp_sym_alg_names, s2k);
if (s2k != PGP_SYM_ALG_PLAIN)
{
DBG1("%N encryption not supported", pgp_sym_alg_names, s2k);
goto end;
}
for (objectID = PRIV_KEY_MODULUS; objectID <= PRIV_KEY_PRIME2; objectID++)
{
chunk_t object;
if (objectID == PRIV_KEY_PRIV_EXP)
{
pgp_sym_alg_t s2k;
/* string-to-key usage */
s2k = pgp_length(&packet, 1);
DBG2("L3 - string-to-key: %d", s2k);
if (s2k == 255 || s2k == 254)
{
DBG1("string-to-key specifiers not supported");
goto end;
}
DBG2(" %N", pgp_sym_alg_names, s2k);
if (s2k != PGP_SYM_ALG_PLAIN)
{
DBG1("%N encryption not supported", pgp_sym_alg_names, s2k);
goto end;
}
}
DBG2("L3 - %s:", privkeyObjects[objectID].name);
object.len = pgp_length(&packet, 2);
if (object.len == PGP_INVALID_LENGTH)
@ -865,6 +870,7 @@ static gmp_rsa_private_key_t *load_pgp(chunk_t blob)
object.ptr = packet.ptr;
packet.ptr += object.len;
packet.len -= object.len;
DBG4("%B", &object);
switch (objectID)
{

View File

@ -33,12 +33,12 @@
/**
* used for initializatin of certs
*/
const cert_t empty_cert = {CERT_NONE, {NULL}};
const cert_t cert_empty = {CERT_NONE, {NULL}};
/**
* extracts the certificate to be sent to the peer
*/
chunk_t get_mycert(cert_t cert)
chunk_t cert_get_encoding(cert_t cert)
{
switch (cert.type)
{
@ -51,6 +51,21 @@ chunk_t get_mycert(cert_t cert)
}
}
public_key_t* cert_get_public_key(const cert_t cert)
{
switch (cert.type)
{
case CERT_PGP:
return cert.u.pgp->public_key;
break;
case CERT_X509_SIGNATURE:
return cert.u.x509->public_key;
break;
default:
return NULL;
}
}
/* load a coded key or certificate file with autodetection
* of binary DER or base64 PEM ASN.1 formats and armored PGP format
*/
@ -142,13 +157,13 @@ private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
}
if (key == NULL)
{
plog("syntax error in %s private key file", pgp ? "PGP":"PKCS#");
plog(" syntax error in %s private key file", pgp ? "PGP":"PKCS#");
}
free(blob.ptr);
}
else
{
plog("error loading RSA private key file");
plog(" error loading RSA private key file");
}
return key;
}
@ -170,7 +185,7 @@ bool load_cert(char *filename, const char *label, cert_t *cert)
if (pgp)
{
pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
*pgpcert = empty_pgpcert;
*pgpcert = pgpcert_empty;
if (parse_pgp(blob, pgpcert, NULL))
{
cert->type = CERT_PGP;

View File

@ -55,16 +55,17 @@ typedef struct {
} cert_t;
/* used for initialization */
extern const cert_t empty_cert;
extern const cert_t cert_empty;
/* do not send certificate requests
* flag set in plutomain.c and used in ipsec_doi.c
*/
extern bool no_cr_send;
extern public_key_t* cert_get_public_key(const cert_t cert);
extern chunk_t cert_get_encoding(cert_t cert);
extern private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
key_type_t type);
extern chunk_t get_mycert(cert_t cert);
extern bool load_coded_file(char *filename, prompt_pass_t *pass,
const char *type, chunk_t *blob, bool *pgp);
extern bool load_cert(char *filename, const char *label, cert_t *cert);

View File

@ -3415,7 +3415,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
return STF_INTERNAL_ERROR;
if (!out_chunk(get_mycert(mycert), &cert_pbs, "CERT"))
if (!out_chunk(cert_get_encoding(mycert), &cert_pbs, "CERT"))
return STF_INTERNAL_ERROR;
close_output_pbs(&cert_pbs);
}
@ -3825,7 +3825,7 @@ main_inI3_outR3_tail(struct msg_digest *md
if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
return STF_INTERNAL_ERROR;
if (!out_chunk(get_mycert(mycert), &cert_pbs, "CERT"))
if (!out_chunk(cert_get_encoding(mycert), &cert_pbs, "CERT"))
return STF_INTERNAL_ERROR;
close_output_pbs(&cert_pbs);
}

View File

@ -71,34 +71,14 @@ struct secret {
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
*/
@ -121,9 +101,9 @@ static const secret_t* get_secret(const struct connection *c,
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;
@ -136,7 +116,7 @@ static const secret_t* get_secret(const struct connection *c,
/* 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)
{
@ -190,10 +170,13 @@ static const secret_t* get_secret(const struct connection *c,
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,
@ -214,7 +197,9 @@ static const secret_t* get_secret(const struct connection *c,
* there are other ids in the list.
*/
if (!asym)
{
break;
}
/* FALLTHROUGH */
case match_default: /* default all */
case match_me | match_default: /* default peer */
@ -281,7 +266,7 @@ bool has_private_key(cert_t cert)
{
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)
{
@ -396,7 +381,20 @@ static err_t process_psk_secret(chunk_t *psk)
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",
@ -414,17 +412,17 @@ const char *rsa_private_keywords[] = {
*/
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())
{
@ -447,12 +445,12 @@ static err_t process_rsa_secret(private_key_t **key)
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.
@ -472,14 +470,14 @@ static err_t process_rsa_secret(private_key_t **key)
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,
@ -491,9 +489,10 @@ static err_t process_rsa_secret(private_key_t **key)
}
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;
}
@ -867,8 +866,9 @@ static void process_secret_records(int whackfd)
{
(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 */
@ -897,7 +897,9 @@ static void process_secret_records(int whackfd)
* will be rediscovered and reported later.
*/
if (pl > sizeof(fn))
{
pl = sizeof(fn);
}
memcpy(fn, flp->filename, pl);
p += pl;
}
@ -1138,7 +1140,9 @@ pubkey_list_t* free_public_keyentry(pubkey_list_t *p)
pubkey_list_t *nxt = p->next;
if (p->key != NULL)
{
unreference_key(&p->key);
}
free(p);
return nxt;
}
@ -1146,7 +1150,9 @@ pubkey_list_t* free_public_keyentry(pubkey_list_t *p)
void free_public_keys(pubkey_list_t **keys)
{
while (*keys != NULL)
{
*keys = free_public_keyentry(*keys);
}
}
/* root of chained public key list */
@ -1186,7 +1192,9 @@ void transfer_to_public_keys(struct gw_info *gateways_from_dns
pubkey_list_t **pp = keys;
while (*pp != NULL)
{
pp = &(*pp)->next;
}
*pp = pubkeys;
pubkeys = *keys;
*keys = NULL;
@ -1255,7 +1263,9 @@ unreference_key(pubkey_t **pkp)
char b[BUF_LEN];
if (pk == NULL)
{
return;
}
/* print stuff */
DBG(DBG_CONTROLMORE,
@ -1269,7 +1279,9 @@ unreference_key(pubkey_t **pkp)
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,
@ -1369,7 +1381,6 @@ void add_pgp_public_key(pgpcert_t *cert , time_t until,
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);
@ -1394,8 +1405,7 @@ void remove_x509_public_key(const x509cert_t *cert)
{
/* 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
{

View File

@ -34,18 +34,19 @@
#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 */
@ -56,8 +57,8 @@ const pgpcert_t empty_pgpcert = {
};
/*
* extracts the length of a PGP packet
/**
* Extracts the length of a PGP packet
*/
static size_t pgp_old_packet_length(chunk_t *blob)
{
@ -70,8 +71,8 @@ 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)
{
@ -84,94 +85,7 @@ static u_char pgp_version(chunk_t *blob)
return version;
}
/*
* Parse OpenPGP public key packet defined in section 5.5.2 of RFC 2440
*/
static bool parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
{
u_char version = pgp_version(packet);
public_key_t *key;
if (version < 3 || version > 4)
{
plog("PGP packet version V%d not supported", version);
return FALSE;
}
/* creation date - 4 bytes */
cert->created = (time_t)pgp_length(packet, 4);
DBG(DBG_PARSING,
DBG_log("L3 - created:");
DBG_log(" %T", &cert->created, TRUE)
)
if (version == 3)
{
/* validity in days - 2 bytes */
cert->until = (time_t)pgp_length(packet, 2);
/* validity of 0 days means that the key never expires */
if (cert->until > 0)
{
cert->until = cert->created + 24*3600*cert->until;
}
DBG(DBG_PARSING,
DBG_log("L3 - until:");
DBG_log(" %T", &cert->until, TRUE);
)
}
/* public key algorithm - 1 byte */
DBG(DBG_PARSING,
DBG_log("L3 - public key algorithm:")
)
switch (pgp_length(packet, 1))
{
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;
if (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");
}
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;
}
return TRUE;
}
/*
/**
* Parse OpenPGP signature packet defined in section 5.2.2 of RFC 2440
*/
static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
@ -183,12 +97,14 @@ static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
/* 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(" size must be 5");
plog(" size must be 5");
return FALSE;
}
@ -213,6 +129,133 @@ static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
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;
}
/* creation date - 4 bytes */
cert->created = (time_t)pgp_length(packet, 4);
DBG(DBG_PARSING,
DBG_log("L3 - created:");
DBG_log(" %T", &cert->created, TRUE)
)
if (cert->version == 3)
{
/* validity in days - 2 bytes */
cert->until = (time_t)pgp_length(packet, 2);
/* validity of 0 days means that the key never expires */
if (cert->until > 0)
{
cert->until = cert->created + 24*3600*cert->until;
}
DBG(DBG_PARSING,
DBG_log("L3 - until:");
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(" %N", pgp_pubkey_alg_names, pubkey_alg)
)
switch (pubkey_alg)
{
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 (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;
}
break;
default:
plog(" non RSA public keys not supported");
return FALSE;
}
return TRUE;
}
/*
* Parse OpenPGP secret key packet defined in section 5.5.3 of RFC 4880
*/
static bool parse_pgp_secretkey_packet(chunk_t *packet, private_key_t **key)
{
pgp_pubkey_alg_t pubkey_alg;
pgpcert_t cert = pgpcert_empty;
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(" %N", pgp_pubkey_alg_names, pubkey_alg)
)
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)
{
DBG(DBG_PARSING,
@ -275,26 +318,26 @@ 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
@ -302,17 +345,20 @@ bool parse_pgp(chunk_t blob, pgpcert_t *cert, private_key_t **key)
/* 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;
}
}
@ -321,8 +367,8 @@ bool parse_pgp(chunk_t blob, pgpcert_t *cert, private_key_t **key)
return TRUE;
}
/*
* compare two OpenPGP certificates
/**
* Compare two OpenPGP certificates
*/
static bool same_pgpcert(pgpcert_t *a, pgpcert_t *b)
{
@ -330,8 +376,8 @@ 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)
{
@ -341,18 +387,17 @@ 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)
{
@ -377,8 +422,9 @@ 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)
{
@ -394,8 +440,8 @@ void release_pgpcert(pgpcert_t *cert)
}
}
/*
* free a PGP certificate
/**
* Free a PGP certificate
*/
void free_pgpcert(pgpcert_t *cert)
{
@ -408,8 +454,8 @@ 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)
{
@ -435,16 +481,16 @@ 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;
}
}

View File

@ -34,6 +34,7 @@ typedef struct pgpcert pgpcert_t;
struct pgpcert {
pgpcert_t *next;
int version;
time_t installed;
int count;
chunk_t certificate;
@ -43,7 +44,7 @@ struct pgpcert {
identification_t *fingerprint;
};
extern const pgpcert_t empty_pgpcert;
extern const pgpcert_t pgpcert_empty;
extern bool parse_pgp(chunk_t blob, pgpcert_t *cert, private_key_t **key);
extern void share_pgpcert(pgpcert_t *cert);
extern void select_pgpcert_id(pgpcert_t *cert, struct id *end_id);

View File

@ -451,7 +451,7 @@ scx_find_cert_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object
};
/* initialize the return argument */
*cert = empty_cert;
*cert = cert_empty;
/* get the length of the attributes first */
CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);