- applied patch from andreas, which allows certificate listing via stroke

This commit is contained in:
Martin Willi
2006-05-19 06:44:08 +00:00
parent 3e61d63a3a
commit 86a7937b45
17 changed files with 343 additions and 117 deletions
+11 -9
View File
@@ -216,22 +216,19 @@ bool is_printablestring(chunk_t str)
/**
* Display a date either in local or UTC time
* TODO: Does not seem to be thread safe
*/
char* timetoa(const time_t *time, bool utc)
void timetoa(char *buf, size_t buflen, const time_t *time, bool utc)
{
static char buf[30];
if (*time == 0)
sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
snprintf(buf, buflen, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
else
{
struct tm *t = (utc)? gmtime(time) : localtime(time);
sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d",
snprintf(buf, buflen, "%s %02d %02d:%02d:%02d%s%04d",
months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
(utc)?" UTC ":" ", t->tm_year + 1900);
}
return buf;
}
/**
@@ -349,8 +346,13 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type)
return;
case ASN1_UTCTIME:
case ASN1_GENERALIZEDTIME:
time = asn1totime(&object, type);
logger->log(logger, CONTROL|LEVEL1, " '%s'", timetoa(&time, TRUE));
{
char buf[TIMETOA_BUF];
time_t time = asn1totime(&object, type);
timetoa(buf, TIMETOA_BUF, &time, TRUE);
logger->log(logger, CONTROL|LEVEL1, " '%s'", buf);
}
return;
default:
break;
+1
View File
@@ -121,6 +121,7 @@ extern int known_oid(chunk_t object);
extern u_int asn1_length(chunk_t *blob);
extern bool is_printablestring(chunk_t str);
extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
extern void timetoa(char *buf, size_t buflen, const time_t *time, bool utc);
extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit);
extern bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx);
extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name);
+51 -23
View File
@@ -40,39 +40,58 @@
* TODO: We may move them in asn1 sometime...
*/
u_int8_t md2_oid[] = {
0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,
0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,
0x04,0x10
const u_int8_t md2_oid[] = {
0x30,0x20,
0x30,0x0c,
0x06,0x08,
0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,
0x05,0x00,
0x04,0x10
};
u_int8_t md5_oid[] = {
0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,
0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,
0x04,0x10
const u_int8_t md5_oid[] = {
0x30,0x20,
0x30,0x0c,
0x06,0x08,
0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
0x05,0x00,
0x04,0x10
};
u_int8_t sha1_oid[] = {
0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,
0x03,0x02,0x1a,0x05,0x00,0x04,0x14
const u_int8_t sha1_oid[] = {
0x30,0x21,
0x30,0x09,
0x06,0x05,
0x2b,0x0e,0x03,0x02,0x1a,
0x05,0x00,
0x04,0x14
};
u_int8_t sha256_oid[] = {
0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,
0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,
0x00,0x04,0x20
const u_int8_t sha256_oid[] = {
0x30,0x31,
0x30,0x0d,
0x06,0x09,
0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,
0x05,0x00,
0x04,0x20
};
u_int8_t sha384_oid[] = {
0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,
0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,
0x00,0x04,0x30
const u_int8_t sha384_oid[] = {
0x30,0x41,
0x30,0x0d,
0x06,0x09,
0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,
0x05,0x00,
0x04,0x30
};
u_int8_t sha512_oid[] = {
0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,
0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,
0x00,0x04,0x40
const u_int8_t sha512_oid[] = {
0x30,0x51,
0x30,0x0d,
0x06,0x09,
0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,
0x05,0x00,
0x04,0x40
};
/* ASN.1 definition public key */
@@ -337,6 +356,14 @@ static mpz_t *get_modulus(private_rsa_public_key_t *this)
return &this->n;
}
/**
* Implementation of rsa_public_key.get_keysize.
*/
static size_t get_keysize(private_rsa_public_key_t *this)
{
return this->k;
}
/**
* Implementation of rsa_public_key.clone.
*/
@@ -373,6 +400,7 @@ private_rsa_public_key_t *rsa_public_key_create_empty(void)
this->public.get_key = (status_t (*) (rsa_public_key_t*,chunk_t*))get_key;
this->public.save_key = (status_t (*) (rsa_public_key_t*,char*))save_key;
this->public.get_modulus = (mpz_t *(*) (rsa_public_key_t*))get_modulus;
this->public.get_keysize = (size_t (*) (rsa_public_key_t*))get_keysize;
this->public.clone = (rsa_public_key_t* (*) (rsa_public_key_t*))_clone;
this->public.destroy = (void (*) (rsa_public_key_t*))destroy;
@@ -104,6 +104,14 @@ struct rsa_public_key_t {
*/
mpz_t *(*get_modulus) (rsa_public_key_t *this);
/**
* @brief Get the size of the modulus in bytes.
*
* @param this calling object
* @return size of the modulus (n) in bytes
*/
size_t (*get_keysize) (rsa_public_key_t *this);
/**
* @brief Clone the public key.
*
+96 -32
View File
@@ -34,9 +34,10 @@
#include <utils/linked_list.h>
#define BUF_LEN 512
#define RSA_MIN_OCTETS (512 / 8)
#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits"
#define RSA_MAX_OCTETS (8192 / 8)
#define BITS_PER_BYTE 8
#define RSA_MIN_OCTETS (1024 / BITS_PER_BYTE)
#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 1024 bits"
#define RSA_MAX_OCTETS (8192 / BITS_PER_BYTE)
#define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits"
logger_t *logger;
@@ -81,20 +82,45 @@ struct private_x509_t {
x509_t public;
/**
* Version of the X509 certificate
* Time when certificate was installed
*/
time_t installed;
/**
* X.509 Certificate in DER format
*/
chunk_t certificate;
/**
* Version of the X.509 certificate
*/
u_int version;
/**
* ID representing the certificates subject
* Serial number of the X.509 certificate
*/
identification_t *subject;
chunk_t serialNumber;
/**
* ID representing the certificate issuer
*/
identification_t *issuer;
/**
* Start time of certificate validity
*/
time_t notBefore;
/**
* End time of certificate validity
*/
time_t notAfter;
/**
* ID representing the certificate subject
*/
identification_t *subject;
/**
* List of identification_t's representing subjectAltNames
*/
@@ -109,41 +135,34 @@ struct private_x509_t {
* List of identification_t's representing crlDistributionPoints
*/
linked_list_t *crlDistributionPoints;
/**
* Subjects RSA public key, if subjectPublicKeyAlgorithm == RSA
* Subject RSA public key, if subjectPublicKeyAlgorithm == RSA
*/
rsa_public_key_t *public_key;
/**
* Subject Key Identifier
*/
chunk_t subjectKeyID;
/**
* Authority Key Identifier
*/
chunk_t authKeyID;
/**
* Authority Key Serial Number
*/
chunk_t authKeySerialNumber;
time_t installed;
u_char authority_flags;
chunk_t x509;
chunk_t tbsCertificate;
chunk_t serialNumber;
/* signature */
int sigAlg;
/* validity */
time_t notBefore;
time_t notAfter;
/* subjectPublicKeyInfo */
chunk_t subjectPublicKey;
/* issuerUniqueID */
/* subjectUniqueID */
/* v3 extensions */
/* extension */
/* extension */
/* extnID */
/* critical */
/* extnValue */
bool isCA;
bool isOcspSigner; /* ocsp */
chunk_t subjectKeyID;
chunk_t authKeyID;
chunk_t authKeySerialNumber;
chunk_t accessLocation; /* ocsp */
/* signatureAlgorithm */
int algorithm;
@@ -649,7 +668,7 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert)
level++;
switch (objectID) {
case X509_OBJ_CERTIFICATE:
cert->x509 = object;
cert->certificate = object;
break;
case X509_OBJ_TBS_CERTIFICATE:
cert->tbsCertificate = object;
@@ -843,9 +862,50 @@ static void destroy(private_x509_t *this)
{
this->public_key->destroy(this->public_key);
}
free(this->certificate.ptr);
free(this);
}
/**
* log certificate
*/
static void log_certificate(private_x509_t *this, logger_t *logger, bool utc)
{
identification_t *subject = this->subject;
identification_t *issuer = this->issuer;
rsa_public_key_t *rsa_key = this->public_key;
char buf[BUF_LEN];
timetoa(buf, BUF_LEN, &this->installed, utc);
logger->log(logger, CONTROL, "%s", buf);
logger->log(logger, CONTROL, " subject: '%s'", subject->get_string(subject));
logger->log(logger, CONTROL, " issuer: '%s'", issuer->get_string(issuer));
chunk_to_hex(buf, BUF_LEN, this->serialNumber);
logger->log(logger, CONTROL, " serial: %s", buf);
timetoa(buf, BUF_LEN, &this->notBefore, utc);
logger->log(logger, CONTROL, " validity: not before %s", buf);
timetoa(buf, BUF_LEN, &this->notAfter, utc);
logger->log(logger, CONTROL, " not after %s", buf);
logger->log(logger, CONTROL, " pubkey: RSA %d bits", BITS_PER_BYTE * rsa_key->get_keysize(rsa_key));
if (this->subjectKeyID.ptr != NULL)
{
chunk_to_hex(buf, BUF_LEN, this->subjectKeyID);
logger->log(logger, CONTROL, " subjkey: %s", buf);
}
if (this->authKeyID.ptr != NULL)
{
chunk_to_hex(buf, BUF_LEN, this->authKeyID);
logger->log(logger, CONTROL, " authkey: %s", buf);
}
if (this->authKeySerialNumber.ptr != NULL)
{
chunk_to_hex(buf, BUF_LEN, this->authKeySerialNumber);
logger->log(logger, CONTROL, " aserial: %s", buf);
}
}
/*
* Described in header.
*/
@@ -859,6 +919,7 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
this->public.get_public_key = (rsa_public_key_t* (*) (x509_t*))get_public_key;
this->public.get_subject = (identification_t* (*) (x509_t*))get_subject;
this->public.get_issuer = (identification_t* (*) (x509_t*))get_issuer;
this->public.log_certificate = (void (*) (x509_t*,logger_t*,bool))log_certificate;
/* initialize */
this->subjectPublicKey = CHUNK_INITIALIZER;
@@ -892,7 +953,7 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
/*
* Described in header.
*/
x509_t *x509_create_from_file(char *filename)
x509_t *x509_create_from_file(const char *filename)
{
bool pgp = FALSE;
chunk_t chunk = CHUNK_INITIALIZER;
@@ -902,6 +963,9 @@ x509_t *x509_create_from_file(char *filename)
return NULL;
cert = x509_create_from_chunk(chunk);
free(chunk.ptr);
if (cert == NULL)
{
free(chunk.ptr);
}
return cert;
}
+12 -2
View File
@@ -28,6 +28,7 @@
#include <crypto/rsa/rsa_public_key.h>
#include <utils/identification.h>
#include <utils/iterator.h>
#include <utils/logger.h>
typedef struct x509_t x509_t;
@@ -103,7 +104,7 @@ struct x509_t {
* @param other second cert for compare
* @return TRUE if signature is equal
*/
bool (*equals) (x509_t *this, x509_t *other);
bool (*equals) (x509_t *this, x509_t *that);
/**
* @brief Destroys the certificate.
@@ -111,6 +112,15 @@ struct x509_t {
* @param this certificate to destroy
*/
void (*destroy) (x509_t *this);
/**
* @brief Log x509 certificate info.
*
* @param this certificate to log
* @param logger logger to be used
* @param utc log dates either in UTC or local time
*/
void (*log_certificate) (x509_t *this, logger_t *logger, bool utc);
};
/**
@@ -131,6 +141,6 @@ x509_t *x509_create_from_chunk(chunk_t chunk);
*
* @ingroup transforms
*/
x509_t *x509_create_from_file(char *filename);
x509_t *x509_create_from_file(const char *filename);
#endif /* X509_H_ */
+28
View File
@@ -101,6 +101,34 @@ bool chunk_equals(chunk_t a, chunk_t b)
return TRUE;
}
/**
* Described in header.
*/
void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk)
{
bool first = TRUE;
buflen--; /* reserve space for null termination */
while (chunk.len >0 && buflen > 2)
{
static char hexdig[] = "0123456789abcdef";
if (first)
{
first = FALSE;
}
else
{
*buf++ = ':'; buflen--;
}
*buf++ = hexdig[(*chunk.ptr >> 4) & 0x0f];
*buf++ = hexdig[ *chunk.ptr++ & 0x0f];
buflen -= 2; chunk.len--;
}
*buf = '\0';
}
/**
* Described in header.
*/
+6
View File
@@ -182,6 +182,12 @@ chunk_t chunk_alloc(size_t bytes);
*/
bool chunk_equals(chunk_t a, chunk_t b);
/**
* Print a chunk in hexadecimal form
* with each byte separated by a colon
*/
void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk);
/**
* Clone a data to a newly allocated buffer
*/
+7
View File
@@ -43,6 +43,13 @@ typedef struct iterator_t iterator_t;
*/
struct iterator_t {
/**
* @brief Return number of list items.
*
* @param this calling object
* @return number of list items
*/
int (*get_count) (iterator_t *this);
/**
* @brief Iterate over all items.
*
+10 -1
View File
@@ -152,7 +152,15 @@ struct private_iterator_t {
};
/**
* Implementation of iterator_t.has_next.
* Implementation of iterator_t.get_count.
*/
static int get_list_count(private_iterator_t *this)
{
return this->list->count;
}
/**
* Implementation of iterator_t.iterate.
*/
static bool iterate(private_iterator_t *this, void** value)
{
@@ -665,6 +673,7 @@ static iterator_t *create_iterator (private_linked_list_t *linked_list,bool forw
{
private_iterator_t *this = malloc_thing(private_iterator_t);
this->public.get_count = (bool (*) (iterator_t *this)) get_list_count;
this->public.iterate = (bool (*) (iterator_t *this, void **value)) iterate;
this->public.has_next = (bool (*) (iterator_t *this)) iterator_has_next;
this->public.current = (status_t (*) (iterator_t *this, void **value)) iterator_current;