added X.509 trust chain verification
This commit is contained in:
parent
c01d911201
commit
6f74bfd6ac
|
@ -91,6 +91,16 @@ struct credential_store_t {
|
|||
*/
|
||||
bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey);
|
||||
|
||||
/**
|
||||
* @brief Verify an X.509 certificate up to trust anchor including revocation checks
|
||||
*
|
||||
* @param this calling object
|
||||
* @param cert certificate to be verified
|
||||
* @param until time until which the cert can be trusted
|
||||
* @return TRUE if trusted
|
||||
*/
|
||||
bool (*verify) (credential_store_t *this, const x509_t *cert, time_t *until);
|
||||
|
||||
/**
|
||||
* @brief If an end certificate does not already exists in the credential store then add it.
|
||||
*
|
||||
|
@ -108,7 +118,7 @@ struct credential_store_t {
|
|||
* @return pointer to the added or already existing certificate
|
||||
*/
|
||||
x509_t* (*add_ca_certificate) (credential_store_t *this, x509_t *cert);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Lists all certificates kept in the local credential store.
|
||||
*
|
||||
|
|
|
@ -25,15 +25,18 @@
|
|||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "local_credential_store.h"
|
||||
|
||||
#include <utils/lexparser.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/logger_manager.h>
|
||||
#include <crypto/certinfo.h>
|
||||
#include <crypto/rsa/rsa_public_key.h>
|
||||
#include <crypto/x509.h>
|
||||
#include <crypto/crl.h>
|
||||
|
||||
#define PATH_BUF 256
|
||||
#include "local_credential_store.h"
|
||||
|
||||
#define PATH_BUF 256
|
||||
#define MAX_CA_PATH_LEN 7
|
||||
|
||||
typedef struct private_local_credential_store_t private_local_credential_store_t;
|
||||
|
||||
|
@ -165,6 +168,236 @@ static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_publ
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_store_t.get_issuer_certificate.
|
||||
*/
|
||||
static x509_t* get_issuer_certificate(private_local_credential_store_t *this, const x509_t *cert)
|
||||
{
|
||||
x509_t *issuer_cert = NULL;
|
||||
|
||||
iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE);
|
||||
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
x509_t *current_cert;
|
||||
|
||||
iterator->current(iterator, (void**)¤t_cert);
|
||||
if (cert->is_issuer(cert, current_cert))
|
||||
{
|
||||
issuer_cert = current_cert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return issuer_cert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_store_t.get_crl.
|
||||
*/
|
||||
static crl_t* get_crl(private_local_credential_store_t *this, const x509_t *issuer)
|
||||
{
|
||||
crl_t *crl = NULL;
|
||||
|
||||
iterator_t *iterator = this->crls->create_iterator(this->crls, TRUE);
|
||||
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
crl_t *current_crl;
|
||||
|
||||
iterator->current(iterator, (void**)¤t_crl);
|
||||
if (current_crl->is_issuer(current_crl, issuer))
|
||||
{
|
||||
crl = current_crl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return crl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the certificate status using CRLs
|
||||
*/
|
||||
static cert_status_t verify_by_crl(private_local_credential_store_t* this, const x509_t *cert,
|
||||
const x509_t *issuer_cert, certinfo_t *certinfo)
|
||||
{
|
||||
crl_t *crl;
|
||||
bool valid_signature;
|
||||
rsa_public_key_t *issuer_public_key;
|
||||
|
||||
|
||||
pthread_mutex_lock(&(this->crls_mutex));
|
||||
|
||||
crl = get_crl(this, issuer_cert);
|
||||
if (crl == NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "crl not found");
|
||||
goto err;
|
||||
}
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "crl found");
|
||||
|
||||
issuer_public_key = issuer_cert->get_public_key(issuer_cert);
|
||||
valid_signature = crl->verify(crl, issuer_public_key);
|
||||
issuer_public_key->destroy(issuer_public_key);
|
||||
|
||||
if (!valid_signature)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "crl signature is invalid");
|
||||
goto err;
|
||||
}
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "crl signature is valid");
|
||||
|
||||
crl->get_status(crl, certinfo);
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&(this->crls_mutex));
|
||||
return certinfo->get_status(certinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the certificate status using OCSP
|
||||
*/
|
||||
static cert_status_t verify_by_ocsp(private_local_credential_store_t* this,
|
||||
const x509_t *cert, certinfo_t *certinfo)
|
||||
{
|
||||
/* TODO implement function */
|
||||
return CERT_UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a public key for the linked list
|
||||
*/
|
||||
static void remove_public_key(private_local_credential_store_t *this, const x509_t *cert)
|
||||
{
|
||||
/* TODO implement function */
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_store_t.verify.
|
||||
*/
|
||||
static bool verify(private_local_credential_store_t *this, const x509_t *cert, time_t *until)
|
||||
{
|
||||
int pathlen;
|
||||
|
||||
*until = UNDEFINED_TIME;
|
||||
|
||||
for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
|
||||
{
|
||||
err_t ugh = NULL;
|
||||
x509_t *issuer_cert;
|
||||
rsa_public_key_t *issuer_public_key;
|
||||
bool valid_signature;
|
||||
|
||||
identification_t *subject = cert->get_subject(cert);
|
||||
identification_t *issuer = cert->get_issuer(cert);
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "subject: '%s'", subject->get_string(subject));
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "issuer: '%s'", issuer->get_string(issuer));
|
||||
|
||||
ugh = cert->is_valid(cert, until);
|
||||
if (ugh != NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "certificate %s", ugh);
|
||||
return FALSE;
|
||||
}
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is valid");
|
||||
|
||||
issuer_cert = get_issuer_certificate(this, cert);
|
||||
if (issuer_cert == NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "issuer certificate not found");
|
||||
return FALSE;
|
||||
}
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "issuer certificate found");
|
||||
|
||||
issuer_public_key = issuer_cert->get_public_key(issuer_cert);
|
||||
valid_signature = cert->verify(cert, issuer_public_key);
|
||||
issuer_public_key->destroy(issuer_public_key);
|
||||
|
||||
if (!valid_signature)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "certificate signature is invalid");
|
||||
return FALSE;
|
||||
}
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate signature is valid");
|
||||
|
||||
/* check if cert is a self-signed root ca */
|
||||
if (pathlen > 0 && cert->is_self_signed(cert))
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "reached self-signed root ca");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t nextUpdate;
|
||||
cert_status_t status;
|
||||
certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
|
||||
|
||||
certinfo->set_nextUpdate(certinfo, *until);
|
||||
|
||||
/* first check certificate revocation using ocsp */
|
||||
status = verify_by_ocsp(this, cert, certinfo);
|
||||
|
||||
/* if ocsp service is not available then fall back to crl */
|
||||
if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && this->strict))
|
||||
{
|
||||
status = verify_by_crl(this, cert, issuer_cert, certinfo);
|
||||
}
|
||||
|
||||
nextUpdate = certinfo->get_nextUpdate(certinfo);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case CERT_GOOD:
|
||||
/* if status information is stale */
|
||||
if (this->strict && nextUpdate < time(NULL))
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good but status is stale");
|
||||
remove_public_key(this, cert);
|
||||
return FALSE;
|
||||
}
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good");
|
||||
|
||||
/* with strict crl policy the public key must have the same
|
||||
* lifetime as the validity of the ocsp status or crl lifetime
|
||||
*/
|
||||
if (this->strict && nextUpdate < *until)
|
||||
*until = nextUpdate;
|
||||
break;
|
||||
case CERT_REVOKED:
|
||||
{
|
||||
u_char buf[TIMETOA_BUF];
|
||||
time_t revocationTime = certinfo->get_revocationTime(certinfo);
|
||||
|
||||
timetoa(buf, TIMETOA_BUF, &revocationTime, TRUE);
|
||||
this->logger->log(this->logger, ERROR, "certificate was revoked on %s, reason: %s",
|
||||
buf, certinfo->get_revocationReason(certinfo));
|
||||
remove_public_key(this, cert);
|
||||
return FALSE;
|
||||
}
|
||||
case CERT_UNKNOWN:
|
||||
case CERT_UNDEFINED:
|
||||
default:
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "certificate status unknown");
|
||||
if (this->strict)
|
||||
{
|
||||
remove_public_key(this, cert);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
certinfo->destroy(certinfo);
|
||||
}
|
||||
/* go up one step in the trust chain */
|
||||
cert = issuer_cert;
|
||||
}
|
||||
this->logger->log(this->logger, ERROR, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a unique certificate to a linked list
|
||||
*/
|
||||
|
@ -600,6 +833,7 @@ local_credential_store_t * local_credential_store_create(bool strict)
|
|||
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
|
||||
this->public.credential_store.has_rsa_private_key = (bool(*)(credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
|
||||
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
|
||||
this->public.credential_store.verify = (bool(*)(credential_store_t*,const x509_t*,time_t*))verify;
|
||||
this->public.credential_store.add_end_certificate = (x509_t*(*)(credential_store_t*,x509_t*))add_end_certificate;
|
||||
this->public.credential_store.add_ca_certificate = (x509_t*(*)(credential_store_t*,x509_t*))add_ca_certificate;
|
||||
this->public.credential_store.log_certificates = (void(*)(credential_store_t*,logger_t*,bool))log_certificates;
|
||||
|
|
|
@ -136,6 +136,7 @@ static x509_t* load_end_certificate(const char *filename, identification_t **idp
|
|||
{
|
||||
identification_t *id = *idp;
|
||||
identification_t *subject = cert->get_subject(cert);
|
||||
time_t until;
|
||||
|
||||
err_t ugh = cert->is_valid(cert, NULL);
|
||||
|
||||
|
@ -149,6 +150,20 @@ static x509_t* load_end_certificate(const char *filename, identification_t **idp
|
|||
id = subject;
|
||||
*idp = id->clone(id);
|
||||
}
|
||||
/* test output */
|
||||
if (charon->credentials->verify(charon->credentials, cert, &until))
|
||||
{
|
||||
char buf[TIMETOA_BUF];
|
||||
|
||||
timetoa(buf, TIMETOA_BUF, &until, TRUE);
|
||||
logger->log(logger, CONTROL, " end entity certificate is trusted until %s", buf);
|
||||
cert->set_until(cert, until);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger->log(logger, ERROR, " end entity certificate is not trusted");
|
||||
}
|
||||
/* end of test output */
|
||||
return charon->credentials->add_end_certificate(charon->credentials, cert);
|
||||
}
|
||||
return NULL;
|
||||
|
@ -305,7 +320,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
|
|||
}
|
||||
if (msg->add_conn.me.cert)
|
||||
{
|
||||
x509_t *cert = load_end_certificate(msg->add_conn.me.cert, &my_id, this->stroke_logger);
|
||||
x509_t *cert = load_end_certificate(msg->add_conn.me.cert, &my_id, this->logger);
|
||||
|
||||
if (my_ca == NULL && !my_ca_same && cert)
|
||||
{
|
||||
|
@ -316,7 +331,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
|
|||
}
|
||||
if (msg->add_conn.other.cert)
|
||||
{
|
||||
x509_t *cert = load_end_certificate(msg->add_conn.other.cert, &other_id, this->stroke_logger);
|
||||
x509_t *cert = load_end_certificate(msg->add_conn.other.cert, &other_id, this->logger);
|
||||
|
||||
if (other_ca == NULL && !other_ca_same && cert)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,7 @@ crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \
|
|||
crypto/hashers/md5_hasher.c crypto/hashers/md5_hasher.h \
|
||||
crypto/prf_plus.h crypto/prf_plus.c \
|
||||
crypto/hmac.c crypto/hmac.h \
|
||||
crypto/certinfo.c crypto/certinfo.h \
|
||||
crypto/x509.c crypto/x509.h \
|
||||
crypto/crl.c crypto/crl.h \
|
||||
crypto/diffie_hellman.c crypto/diffie_hellman.h \
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
/**
|
||||
* @file certinfo.c
|
||||
*
|
||||
* @brief Implementation of certinfo_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <types.h>
|
||||
#include <definitions.h>
|
||||
|
||||
#include "certinfo.h"
|
||||
|
||||
typedef struct private_certinfo_t private_certinfo_t;
|
||||
|
||||
/**
|
||||
* Private data of a certinfo_t object.
|
||||
*/
|
||||
struct private_certinfo_t {
|
||||
/**
|
||||
* Public interface for this certificate status information object.
|
||||
*/
|
||||
certinfo_t public;
|
||||
|
||||
/**
|
||||
* Serial number of the certificate
|
||||
*/
|
||||
chunk_t serialNumber;
|
||||
|
||||
/**
|
||||
* Certificate status
|
||||
*/
|
||||
cert_status_t status;
|
||||
|
||||
/**
|
||||
* Time when the certificate status info was generated
|
||||
*/
|
||||
time_t thisUpdate;
|
||||
|
||||
/**
|
||||
* Time when an updated certifcate status info will be available
|
||||
*/
|
||||
time_t nextUpdate;
|
||||
|
||||
/**
|
||||
* Time of certificate revocation
|
||||
*/
|
||||
time_t revocationTime;
|
||||
|
||||
/**
|
||||
* Reason of certificate revocation
|
||||
*/
|
||||
crl_reason_t revocationReason;
|
||||
};
|
||||
|
||||
/**
|
||||
* RFC 2459 CRL reason codes
|
||||
*/
|
||||
static const char *const crl_reason_name[] = {
|
||||
"unspecified",
|
||||
"key compromise",
|
||||
"ca compromise",
|
||||
"affiliation changed",
|
||||
"superseded",
|
||||
"cessation of operation",
|
||||
"certificate hold",
|
||||
"reason #7",
|
||||
"remove from crl"
|
||||
};
|
||||
|
||||
enum_names crl_reason_names =
|
||||
{ REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, crl_reason_name, NULL};
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_serialNumber
|
||||
*/
|
||||
static chunk_t get_serialNumber(const private_certinfo_t *this)
|
||||
{
|
||||
return this->serialNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_status
|
||||
*/
|
||||
static void set_status(private_certinfo_t *this, cert_status_t status)
|
||||
{
|
||||
this->status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_status
|
||||
*/
|
||||
static cert_status_t get_status(const private_certinfo_t *this)
|
||||
{
|
||||
return this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_nextUpdate
|
||||
*/
|
||||
static void set_nextUpdate(private_certinfo_t *this, time_t nextUpdate)
|
||||
{
|
||||
this->nextUpdate = nextUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_nextUpdate
|
||||
*/
|
||||
static time_t get_nextUpdate(const private_certinfo_t *this)
|
||||
{
|
||||
return this->nextUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_revocationTime
|
||||
*/
|
||||
static void set_revocationTime(private_certinfo_t *this, time_t revocationTime)
|
||||
{
|
||||
this->revocationTime = revocationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_revocationTime
|
||||
*/
|
||||
static time_t get_revocationTime(const private_certinfo_t *this)
|
||||
{
|
||||
return this->revocationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_revocationReason
|
||||
*/
|
||||
static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason)
|
||||
{
|
||||
this->revocationReason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_revocationReason
|
||||
*/
|
||||
static const char *get_revocationReason(const private_certinfo_t *this)
|
||||
{
|
||||
return enum_name(&crl_reason_names, this->revocationReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.destroy
|
||||
*/
|
||||
static void destroy(private_certinfo_t *this)
|
||||
{
|
||||
free(this->serialNumber.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
certinfo_t *certinfo_create(chunk_t serial)
|
||||
{
|
||||
private_certinfo_t *this = malloc_thing(private_certinfo_t);
|
||||
|
||||
/* initialize */
|
||||
this->serialNumber = chunk_clone(serial);
|
||||
this->status = CERT_UNDEFINED;
|
||||
this->nextUpdate = UNDEFINED_TIME;
|
||||
this->revocationTime = UNDEFINED_TIME;
|
||||
this->revocationReason = REASON_UNSPECIFIED;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_serialNumber = (chunk_t (*) (const certinfo_t*))get_serialNumber;
|
||||
this->public.set_status = (void (*) (certinfo_t*,cert_status_t))set_status;
|
||||
this->public.get_status = (cert_status_t (*) (const certinfo_t*))get_status;
|
||||
this->public.set_nextUpdate = (void (*) (certinfo_t*,time_t))set_nextUpdate;
|
||||
this->public.get_nextUpdate = (time_t (*) (const certinfo_t*))get_nextUpdate;
|
||||
this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
|
||||
this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime;
|
||||
this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason;
|
||||
this->public.get_revocationReason = (const char *(*) (const certinfo_t*))get_revocationReason;
|
||||
this->public.destroy = (void (*) (certinfo_t*))destroy;
|
||||
|
||||
return &this->public;
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
* @file certinfo.h
|
||||
*
|
||||
* @brief Interface of certinfo_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CERTINFO_H_
|
||||
#define CERTINFO_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <definitions.h>
|
||||
|
||||
/**
|
||||
* RFC 2560 OCSP - certificate status
|
||||
*/
|
||||
typedef enum {
|
||||
CERT_GOOD = 0,
|
||||
CERT_REVOKED = 1,
|
||||
CERT_UNKNOWN = 2,
|
||||
CERT_UNDEFINED = 3
|
||||
} cert_status_t;
|
||||
|
||||
/**
|
||||
* RFC 2459 CRL reason codes
|
||||
*/
|
||||
|
||||
extern enum_names crl_reason_names;
|
||||
|
||||
typedef enum {
|
||||
REASON_UNSPECIFIED = 0,
|
||||
REASON_KEY_COMPROMISE = 1,
|
||||
REASON_CA_COMPROMISE = 2,
|
||||
REASON_AFFILIATION_CHANGED = 3,
|
||||
REASON_SUPERSEDED = 4,
|
||||
REASON_CESSATION_OF_OPERATON = 5,
|
||||
REASON_CERTIFICATE_HOLD = 6,
|
||||
REASON_REMOVE_FROM_CRL = 8
|
||||
} crl_reason_t;
|
||||
|
||||
typedef struct certinfo_t certinfo_t;
|
||||
|
||||
/**
|
||||
* @brief X.509 certificate status information
|
||||
*
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
struct certinfo_t {
|
||||
|
||||
/**
|
||||
* @brief Get serial number
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @return serialNumber
|
||||
*/
|
||||
chunk_t (*get_serialNumber) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set certificate status
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @param status status
|
||||
*/
|
||||
void (*set_status) (certinfo_t *this, cert_status_t status);
|
||||
|
||||
/**
|
||||
* @brief Get certificate status
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @return status
|
||||
*/
|
||||
cert_status_t (*get_status) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set nextUpdate
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @return nextUpdate
|
||||
*/
|
||||
void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
|
||||
|
||||
/**
|
||||
* @brief Get nextUpdate
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @return nextUpdate
|
||||
*/
|
||||
time_t (*get_nextUpdate) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set revocationTime
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @param revocationTime revocationTime
|
||||
*/
|
||||
void (*set_revocationTime) (certinfo_t *this, time_t revocationTime);
|
||||
|
||||
/**
|
||||
* @brief Get revocationTime
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @return revocationTime
|
||||
*/
|
||||
time_t (*get_revocationTime) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set revocationReason
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @param reason revocationReason
|
||||
*/
|
||||
void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason);
|
||||
|
||||
/**
|
||||
* @brief Get revocationReason
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @return revocationReason
|
||||
*/
|
||||
const char *(*get_revocationReason) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys the certinfo_t object.
|
||||
*
|
||||
* @param this crl to destroy
|
||||
*/
|
||||
void (*destroy) (certinfo_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a certinfo_t object.
|
||||
*
|
||||
* @param serial chunk serial number of the certificate
|
||||
* @return created certinfo_t object
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
certinfo_t *certinfo_create(chunk_t serial);
|
||||
|
||||
#endif /* CERTINFO_H_ */
|
|
@ -33,8 +33,9 @@
|
|||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
#include "crl.h"
|
||||
#include "certinfo.h"
|
||||
#include "x509.h"
|
||||
#include "crl.h"
|
||||
|
||||
#define CRL_WARNING_INTERVAL 7 /* days */
|
||||
|
||||
|
@ -132,8 +133,9 @@ struct private_crl_t {
|
|||
chunk_t signature;
|
||||
};
|
||||
|
||||
/* ASN.1 definition of an X.509 certificate revocation list */
|
||||
|
||||
/**
|
||||
* ASN.1 definition of an X.509 certificate revocation list
|
||||
*/
|
||||
static const asn1Object_t crlObjects[] = {
|
||||
{ 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
|
||||
{ 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
|
||||
|
@ -201,7 +203,8 @@ static crl_reason_t parse_crl_reasonCode(chunk_t object)
|
|||
{
|
||||
reason = *object.ptr;
|
||||
}
|
||||
/* TODO logger->log(logger, CONTROL|LEVEL2, " '%s'", enum_name(&crl_reason_names, reason)) */
|
||||
logger->log(logger, CONTROL|LEVEL2, " '%s'", enum_name(&crl_reason_names, reason));
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
@ -331,14 +334,6 @@ static err_t is_valid(const private_crl_t *this, time_t *until, bool strict)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.is_newer
|
||||
*/
|
||||
static bool is_newer(const private_crl_t *this, const private_crl_t *other)
|
||||
{
|
||||
return (this->nextUpdate > other->nextUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.get_issuer
|
||||
*/
|
||||
|
@ -359,7 +354,61 @@ static bool equals_issuer(const private_crl_t *this, const private_crl_t *other)
|
|||
}
|
||||
|
||||
/**
|
||||
* destroy
|
||||
* Implements crl_t.is_issuer
|
||||
*/
|
||||
static bool is_issuer(const private_crl_t *this, const x509_t *issuer)
|
||||
{
|
||||
return (this->authKeyID.ptr)
|
||||
? chunk_equals(this->authKeyID, issuer->get_subjectKeyID(issuer))
|
||||
: (this->issuer->equals(this->issuer, issuer->get_subject(issuer))
|
||||
&& chunk_equals_or_null(this->authKeySerialNumber, issuer->get_serialNumber(issuer)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.is_newer
|
||||
*/
|
||||
static bool is_newer(const private_crl_t *this, const private_crl_t *other)
|
||||
{
|
||||
return (this->nextUpdate > other->nextUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.verify
|
||||
*/
|
||||
static bool verify(const private_crl_t *this, const rsa_public_key_t *signer)
|
||||
{
|
||||
return signer->verify_emsa_pkcs1_signature(signer, this->tbsCertList, this->signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.get_status
|
||||
*/
|
||||
static void get_status(const private_crl_t *this, certinfo_t *certinfo)
|
||||
{
|
||||
chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
|
||||
iterator_t *iterator = this->revokedCertificates->create_iterator(this->revokedCertificates, TRUE);
|
||||
|
||||
certinfo->set_nextUpdate(certinfo, this->nextUpdate);
|
||||
certinfo->set_status(certinfo, CERT_GOOD);
|
||||
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
revokedCert_t *revokedCert;
|
||||
|
||||
iterator->current(iterator, (void**)&revokedCert);
|
||||
if (chunk_equals(serialNumber, revokedCert->userCertificate))
|
||||
{
|
||||
certinfo->set_status(certinfo, CERT_REVOKED);
|
||||
certinfo->set_revocationTime(certinfo, revokedCert->revocationDate);
|
||||
certinfo->set_revocationReason(certinfo, revokedCert->revocationReason);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.destroy
|
||||
*/
|
||||
static void destroy(private_crl_t *this)
|
||||
{
|
||||
|
@ -440,12 +489,15 @@ crl_t *crl_create_from_chunk(chunk_t chunk)
|
|||
this->authKeySerialNumber = CHUNK_INITIALIZER;
|
||||
|
||||
/* public functions */
|
||||
this->public.is_valid = (err_t (*) (const crl_t*,time_t*))is_valid;
|
||||
this->public.destroy = (void (*) (crl_t*))destroy;
|
||||
this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer;
|
||||
this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer;
|
||||
this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer;
|
||||
this->public.is_valid = (err_t (*) (const crl_t*,time_t*,bool))is_valid;
|
||||
this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
|
||||
this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
|
||||
this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
|
||||
this->public.log_crl = (void (*) (const crl_t*,logger_t*,bool,bool))log_crl;
|
||||
this->public.destroy = (void (*) (crl_t*))destroy;
|
||||
|
||||
/* we do not use a per-instance logger right now, since its not always accessible */
|
||||
logger = logger_manager->get_logger(logger_manager, ASN1);
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
#include <types.h>
|
||||
#include <definitions.h>
|
||||
#include <crypto/rsa/rsa_public_key.h>
|
||||
#include <crypto/certinfo.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/iterator.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
|
||||
typedef struct crl_t crl_t;
|
||||
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@ struct crl_t {
|
|||
* @return issuers ID
|
||||
*/
|
||||
identification_t *(*get_issuer) (const crl_t *this);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check if both crls have the same issuer.
|
||||
*
|
||||
|
@ -65,15 +65,14 @@ struct crl_t {
|
|||
bool (*equals_issuer) (const crl_t *this, const crl_t *other);
|
||||
|
||||
/**
|
||||
* @brief Check if a crl is trustworthy
|
||||
* @brief Check if ia candidate cert is the issuer of the crl
|
||||
*
|
||||
* Use the issuer's public key to verify
|
||||
* the trustworthiness of a crl.
|
||||
*
|
||||
* @todo implement!
|
||||
* @param this calling object
|
||||
* @param issuer candidate issuer of the crl
|
||||
* @return TRUE if issuer
|
||||
*/
|
||||
bool (*verify) (const crl_t *this, rsa_public_key_t *signer);
|
||||
|
||||
bool (*is_issuer) (const crl_t *this, const x509_t *issuer);
|
||||
|
||||
/**
|
||||
* @brief Checks the validity interval of the crl
|
||||
*
|
||||
|
@ -94,13 +93,21 @@ struct crl_t {
|
|||
bool (*is_newer) (const crl_t *this, const crl_t *other);
|
||||
|
||||
/**
|
||||
* @brief Check if a certificate has been revoked.
|
||||
*
|
||||
* This function uses the certificate's serialNumber
|
||||
* to get the revocation status.
|
||||
* @brief Check if a crl is trustworthy.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param signer signer's RSA public key
|
||||
* @return TRUE if crl is trustworthy
|
||||
*/
|
||||
bool (*get_status) (const crl_t *this, chunk_t serial);
|
||||
bool (*verify) (const crl_t *this, const rsa_public_key_t *signer);
|
||||
|
||||
/**
|
||||
* @brief Get the certificate status
|
||||
*
|
||||
* @param this calling object
|
||||
* @param certinfo certinfo is updated
|
||||
*/
|
||||
void (*get_status) (const crl_t *this, certinfo_t *certinfo);
|
||||
|
||||
/**
|
||||
* @brief Destroys the crl.
|
||||
|
|
|
@ -141,7 +141,7 @@ struct private_rsa_public_key_t {
|
|||
* @param data data to process
|
||||
* @return processed data
|
||||
*/
|
||||
chunk_t (*rsaep) (private_rsa_public_key_t *this, chunk_t data);
|
||||
chunk_t (*rsaep) (const private_rsa_public_key_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Implements the RSASVP1 algorithm specified in PKCS#1.
|
||||
|
@ -150,7 +150,7 @@ struct private_rsa_public_key_t {
|
|||
* @param data data to process
|
||||
* @return processed data
|
||||
*/
|
||||
chunk_t (*rsavp1) (private_rsa_public_key_t *this, chunk_t data);
|
||||
chunk_t (*rsavp1) (const private_rsa_public_key_t *this, chunk_t data);
|
||||
};
|
||||
|
||||
private_rsa_public_key_t *rsa_public_key_create_empty(void);
|
||||
|
@ -158,7 +158,7 @@ private_rsa_public_key_t *rsa_public_key_create_empty(void);
|
|||
/**
|
||||
* Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1
|
||||
*/
|
||||
static chunk_t rsaep(private_rsa_public_key_t *this, chunk_t data)
|
||||
static chunk_t rsaep(const private_rsa_public_key_t *this, chunk_t data)
|
||||
{
|
||||
mpz_t m, c;
|
||||
chunk_t encrypted;
|
||||
|
@ -182,7 +182,7 @@ static chunk_t rsaep(private_rsa_public_key_t *this, chunk_t data)
|
|||
/**
|
||||
* Implementation of rsa_public_key.verify_emsa_pkcs1_signature.
|
||||
*/
|
||||
static status_t verify_emsa_pkcs1_signature(private_rsa_public_key_t *this, chunk_t data, chunk_t signature)
|
||||
static status_t verify_emsa_pkcs1_signature(const private_rsa_public_key_t *this, chunk_t data, chunk_t signature)
|
||||
{
|
||||
hasher_t *hasher = NULL;
|
||||
chunk_t hash;
|
||||
|
@ -291,7 +291,7 @@ end:
|
|||
/**
|
||||
* Implementation of rsa_public_key.get_key.
|
||||
*/
|
||||
static status_t get_key(private_rsa_public_key_t *this, chunk_t *key)
|
||||
static status_t get_key(const private_rsa_public_key_t *this, chunk_t *key)
|
||||
{
|
||||
chunk_t n, e;
|
||||
|
||||
|
@ -313,7 +313,7 @@ static status_t get_key(private_rsa_public_key_t *this, chunk_t *key)
|
|||
/**
|
||||
* Implementation of rsa_public_key.save_key.
|
||||
*/
|
||||
static status_t save_key(private_rsa_public_key_t *this, char *file)
|
||||
static status_t save_key(const private_rsa_public_key_t *this, char *file)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ static status_t save_key(private_rsa_public_key_t *this, char *file)
|
|||
/**
|
||||
* Implementation of rsa_public_key.get_modulus.
|
||||
*/
|
||||
static mpz_t *get_modulus(private_rsa_public_key_t *this)
|
||||
static mpz_t *get_modulus(const private_rsa_public_key_t *this)
|
||||
{
|
||||
return &this->n;
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ static mpz_t *get_modulus(private_rsa_public_key_t *this)
|
|||
/**
|
||||
* Implementation of rsa_public_key.get_keysize.
|
||||
*/
|
||||
static size_t get_keysize(private_rsa_public_key_t *this)
|
||||
static size_t get_keysize(const private_rsa_public_key_t *this)
|
||||
{
|
||||
return this->k;
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ static size_t get_keysize(private_rsa_public_key_t *this)
|
|||
/**
|
||||
* Implementation of rsa_public_key.get_keyid.
|
||||
*/
|
||||
static chunk_t get_keyid(private_rsa_public_key_t *this)
|
||||
static chunk_t get_keyid(const private_rsa_public_key_t *this)
|
||||
{
|
||||
return this->keyid;
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ static chunk_t get_keyid(private_rsa_public_key_t *this)
|
|||
/**
|
||||
* Implementation of rsa_public_key.clone.
|
||||
*/
|
||||
static rsa_public_key_t* _clone(private_rsa_public_key_t *this)
|
||||
static rsa_public_key_t* _clone(const private_rsa_public_key_t *this)
|
||||
{
|
||||
private_rsa_public_key_t *clone = rsa_public_key_create_empty();
|
||||
|
||||
|
@ -376,13 +376,13 @@ private_rsa_public_key_t *rsa_public_key_create_empty(void)
|
|||
private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.verify_emsa_pkcs1_signature = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t))verify_emsa_pkcs1_signature;
|
||||
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.get_keyid = (chunk_t (*) (rsa_public_key_t*))get_keyid;
|
||||
this->public.clone = (rsa_public_key_t* (*) (rsa_public_key_t*))_clone;
|
||||
this->public.verify_emsa_pkcs1_signature = (status_t (*) (const rsa_public_key_t*,chunk_t,chunk_t))verify_emsa_pkcs1_signature;
|
||||
this->public.get_key = (status_t (*) (const rsa_public_key_t*,chunk_t*))get_key;
|
||||
this->public.save_key = (status_t (*) (const rsa_public_key_t*,char*))save_key;
|
||||
this->public.get_modulus = (mpz_t *(*) (const rsa_public_key_t*))get_modulus;
|
||||
this->public.get_keysize = (size_t (*) (const rsa_public_key_t*))get_keysize;
|
||||
this->public.get_keyid = (chunk_t (*) (const rsa_public_key_t*))get_keyid;
|
||||
this->public.clone = (rsa_public_key_t* (*) (const rsa_public_key_t*))_clone;
|
||||
this->public.destroy = (void (*) (rsa_public_key_t*))destroy;
|
||||
|
||||
/* private functions */
|
||||
|
|
|
@ -67,7 +67,7 @@ struct rsa_public_key_t {
|
|||
* - INVALID_ARG, if signature is not a signature
|
||||
* - FAILED if signature invalid or unable to verify
|
||||
*/
|
||||
status_t (*verify_emsa_pkcs1_signature) (rsa_public_key_t *this, chunk_t data, chunk_t signature);
|
||||
status_t (*verify_emsa_pkcs1_signature) (const rsa_public_key_t *this, chunk_t data, chunk_t signature);
|
||||
|
||||
/**
|
||||
* @brief Gets the key.
|
||||
|
@ -83,7 +83,7 @@ struct rsa_public_key_t {
|
|||
* - SUCCESS
|
||||
* - INVALID_STATE, if key not set
|
||||
*/
|
||||
status_t (*get_key) (rsa_public_key_t *this, chunk_t *key);
|
||||
status_t (*get_key) (const rsa_public_key_t *this, chunk_t *key);
|
||||
|
||||
/**
|
||||
* @brief Saves a key to a file.
|
||||
|
@ -94,7 +94,7 @@ struct rsa_public_key_t {
|
|||
* @param file file to which the key should be written.
|
||||
* @return NOT_SUPPORTED
|
||||
*/
|
||||
status_t (*save_key) (rsa_public_key_t *this, char *file);
|
||||
status_t (*save_key) (const rsa_public_key_t *this, char *file);
|
||||
|
||||
/**
|
||||
* @brief Get the modulus of the key.
|
||||
|
@ -102,7 +102,7 @@ struct rsa_public_key_t {
|
|||
* @param this calling object
|
||||
* @return modulus (n) of the key
|
||||
*/
|
||||
mpz_t *(*get_modulus) (rsa_public_key_t *this);
|
||||
mpz_t *(*get_modulus) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the size of the modulus in bytes.
|
||||
|
@ -110,7 +110,7 @@ struct rsa_public_key_t {
|
|||
* @param this calling object
|
||||
* @return size of the modulus (n) in bytes
|
||||
*/
|
||||
size_t (*get_keysize) (rsa_public_key_t *this);
|
||||
size_t (*get_keysize) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the keyid formed as the SHA-1 hash of a publicKeyInfo object.
|
||||
|
@ -118,7 +118,7 @@ struct rsa_public_key_t {
|
|||
* @param this calling object
|
||||
* @return keyid in the form of a SHA-1 hash
|
||||
*/
|
||||
chunk_t (*get_keyid) (rsa_public_key_t *this);
|
||||
chunk_t (*get_keyid) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Clone the public key.
|
||||
|
@ -126,7 +126,7 @@ struct rsa_public_key_t {
|
|||
* @param this public key to clone
|
||||
* @return clone of this
|
||||
*/
|
||||
rsa_public_key_t *(*clone) (rsa_public_key_t *this);
|
||||
rsa_public_key_t *(*clone) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys the public key.
|
||||
|
|
|
@ -73,6 +73,11 @@ struct private_x509_t {
|
|||
*/
|
||||
time_t installed;
|
||||
|
||||
/**
|
||||
* Time until certificate can be trusted
|
||||
*/
|
||||
time_t until;
|
||||
|
||||
/**
|
||||
* X.509 Certificate in DER format
|
||||
*/
|
||||
|
@ -909,6 +914,14 @@ static bool is_ca(const private_x509_t *this)
|
|||
return this->isCA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.is_self_signed
|
||||
*/
|
||||
static bool is_self_signed(const private_x509_t *this)
|
||||
{
|
||||
return this->subject->equals(this->subject, this->issuer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.equals_subjectAltName
|
||||
*/
|
||||
|
@ -932,6 +945,17 @@ static bool equals_subjectAltName(const private_x509_t *this, identification_t *
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.is_issuer
|
||||
*/
|
||||
static bool is_issuer(const private_x509_t *this, const private_x509_t *issuer)
|
||||
{
|
||||
return (this->authKeyID.ptr)
|
||||
? chunk_equals(this->authKeyID, issuer->subjectKeyID)
|
||||
: (this->issuer->equals(this->issuer, issuer->subject)
|
||||
&& chunk_equals_or_null(this->authKeySerialNumber, issuer->serialNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.get_public_key
|
||||
*/
|
||||
|
@ -940,6 +964,30 @@ static rsa_public_key_t *get_public_key(const private_x509_t *this)
|
|||
return this->public_key->clone(this->public_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.get_serialNumber
|
||||
*/
|
||||
static chunk_t get_serialNumber(const private_x509_t *this)
|
||||
{
|
||||
return this->serialNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.get_subjectKeyID
|
||||
*/
|
||||
static chunk_t get_subjectKeyID(const private_x509_t *this)
|
||||
{
|
||||
return this->subjectKeyID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.get_issuer
|
||||
*/
|
||||
static identification_t *get_issuer(const private_x509_t *this)
|
||||
{
|
||||
return this->issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.get_subject
|
||||
*/
|
||||
|
@ -949,11 +997,19 @@ static identification_t *get_subject(const private_x509_t *this)
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.get_issuer
|
||||
* Implements x509_t.set_until
|
||||
*/
|
||||
static identification_t *get_issuer(const private_x509_t *this)
|
||||
static void set_until(private_x509_t *this, time_t until)
|
||||
{
|
||||
return this->issuer;
|
||||
this->until = until;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509_t.verify
|
||||
*/
|
||||
static bool verify(const private_x509_t *this, const rsa_public_key_t *signer)
|
||||
{
|
||||
return signer->verify_emsa_pkcs1_signature(signer, this->tbsCertificate, this->signature);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1060,8 +1116,11 @@ static void log_certificate(const private_x509_t *this, logger_t *logger, bool u
|
|||
logger->log(logger, CONTROL, " not after %s %s", buf,
|
||||
check_expiry(this->notAfter, CERT_WARNING_INTERVAL, TRUE));
|
||||
|
||||
logger->log(logger, CONTROL, " pubkey: RSA %d bits%s",
|
||||
BITS_PER_BYTE * pubkey->get_keysize(pubkey), has_key? ", has private key":"");
|
||||
timetoa(buf, BUF_LEN, &this->until, utc);
|
||||
logger->log(logger, CONTROL, " pubkey: RSA %d bits%s, until %s",
|
||||
BITS_PER_BYTE * pubkey->get_keysize(pubkey),
|
||||
has_key? ", has private key":"", buf);
|
||||
|
||||
chunk_to_hex(buf, BUF_LEN, pubkey->get_keyid(pubkey));
|
||||
logger->log(logger, CONTROL, " keyid: %s", buf);
|
||||
|
||||
|
@ -1103,12 +1162,18 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
|
|||
/* public functions */
|
||||
this->public.equals = (bool (*) (const x509_t*,const x509_t*))equals;
|
||||
this->public.equals_subjectAltName = (bool (*) (const x509_t*,identification_t*))equals_subjectAltName;
|
||||
this->public.is_issuer = (bool (*) (const x509_t*,const x509_t*))is_issuer;
|
||||
this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid;
|
||||
this->public.is_ca = (bool (*) (const x509_t*))is_ca;
|
||||
this->public.destroy = (void (*) (x509_t*))destroy;
|
||||
this->public.is_self_signed = (bool (*) (const x509_t*))is_self_signed;
|
||||
this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key;
|
||||
this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject;
|
||||
this->public.get_serialNumber = (chunk_t (*) (const x509_t*))get_serialNumber;
|
||||
this->public.get_subjectKeyID = (chunk_t (*) (const x509_t*))get_subjectKeyID;
|
||||
this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer;
|
||||
this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject;
|
||||
this->public.set_until = (void (*) (x509_t*,time_t))set_until;
|
||||
this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify;
|
||||
this->public.destroy = (void (*) (x509_t*))destroy;
|
||||
this->public.log_certificate = (void (*) (const x509_t*,logger_t*,bool,bool))log_certificate;
|
||||
|
||||
/* we do not use a per-instance logger right now, since its not always accessible */
|
||||
|
@ -1127,7 +1192,8 @@ x509_t *x509_create_from_chunk(chunk_t chunk)
|
|||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set trusted lifetime of public key to notAfter */
|
||||
this->until = this->notAfter;
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,14 @@ typedef struct x509_t x509_t;
|
|||
*/
|
||||
struct x509_t {
|
||||
|
||||
/**
|
||||
* @brief Set trusted public key life.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param until time until public key is trusted
|
||||
*/
|
||||
void (*set_until) (x509_t *this, time_t until);
|
||||
|
||||
/**
|
||||
* @brief Get the RSA public key from the certificate.
|
||||
*
|
||||
|
@ -55,9 +63,25 @@ struct x509_t {
|
|||
* @return public_key
|
||||
*/
|
||||
rsa_public_key_t *(*get_public_key) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get serial number from the certificate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return serialNumber
|
||||
*/
|
||||
chunk_t (*get_serialNumber) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the certificate issuers ID.
|
||||
* @brief Get serial number from the certificate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return subjectKeyID
|
||||
*/
|
||||
chunk_t (*get_subjectKeyID) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the certificate issuer's ID.
|
||||
*
|
||||
* The resulting ID is always a identification_t
|
||||
* of type ID_DER_ASN1_DN.
|
||||
|
@ -81,19 +105,10 @@ struct x509_t {
|
|||
/**
|
||||
* @brief Check if a certificate is trustworthy
|
||||
*
|
||||
* Use the issuer's public key to verify
|
||||
* the trustworthiness of a certificate.
|
||||
*
|
||||
* @todo implement!
|
||||
* @param this calling object
|
||||
* @param signer signer's RSA public key
|
||||
*/
|
||||
bool (*verify) (const x509_t *this, rsa_public_key_t *signer);
|
||||
|
||||
/**
|
||||
* @brief Get the key identifier of the public key.
|
||||
*
|
||||
* @todo implement!
|
||||
*/
|
||||
chunk_t (*get_subject_key_identifier) (const x509_t *this);
|
||||
bool (*verify) (const x509_t *this, const rsa_public_key_t *signer);
|
||||
|
||||
/**
|
||||
* @brief Compare two certificates.
|
||||
|
@ -102,7 +117,7 @@ struct x509_t {
|
|||
*
|
||||
* @param this first cert for compare
|
||||
* @param other second cert for compare
|
||||
* @return TRUE if signature is equal
|
||||
* @return TRUE if signature is equal
|
||||
*/
|
||||
bool (*equals) (const x509_t *this, const x509_t *that);
|
||||
|
||||
|
@ -111,16 +126,25 @@ struct x509_t {
|
|||
*
|
||||
* @param this certificate being examined
|
||||
* @param id id which is being compared to the subjectAltNames
|
||||
* @return TRUE if a match is found
|
||||
* @return TRUE if a match is found
|
||||
*/
|
||||
bool (*equals_subjectAltName) (const x509_t *this, identification_t *id);
|
||||
|
||||
/**
|
||||
* @brief Checks if the subject of the other cert is the issuer of this cert.
|
||||
*
|
||||
* @param this certificate
|
||||
* @param issuer potential issuer certificate
|
||||
* @return TRUE if issuer is found
|
||||
*/
|
||||
bool (*is_issuer) (const x509_t *this, const x509_t *issuer);
|
||||
|
||||
/**
|
||||
* @brief Checks the validity interval of the certificate
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @param until until = min(until, notAfter)
|
||||
* @return NULL if the certificate is valid
|
||||
* @return NULL if the certificate is valid
|
||||
*/
|
||||
err_t (*is_valid) (const x509_t *this, time_t *until);
|
||||
|
||||
|
@ -128,10 +152,18 @@ struct x509_t {
|
|||
* @brief Returns the CA basic constraints flag
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @return TRUE if the CA flag is set
|
||||
* @return TRUE if the CA flag is set
|
||||
*/
|
||||
bool (*is_ca) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Checks if the certificate is self-signed (subject equals issuer)
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @return TRUE if self-signed
|
||||
*/
|
||||
bool (*is_self_signed) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys the certificate.
|
||||
*
|
||||
|
@ -154,7 +186,7 @@ struct x509_t {
|
|||
* @brief Read a x509 certificate from a DER encoded blob.
|
||||
*
|
||||
* @param chunk chunk containing DER encoded data
|
||||
* @return created x509_t certificate, or NULL if invalid.
|
||||
* @return created x509_t certificate, or NULL if invlid.
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "definitions.h"
|
||||
|
||||
/*
|
||||
|
@ -38,3 +40,19 @@ char *mapping_find(mapping_t * maps, int value)
|
|||
}
|
||||
return "INVALID MAPPING";
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
const char *enum_name(enum_names *ed, unsigned long val)
|
||||
{
|
||||
enum_names *p;
|
||||
|
||||
for (p = ed; p != NULL; p = p->en_next_range)
|
||||
{
|
||||
if (p->en_first <= val && val <= p->en_last)
|
||||
return p->en_names[val - p->en_first];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -135,4 +135,22 @@ struct mapping_t
|
|||
*/
|
||||
char *mapping_find(mapping_t *mappings, int value);
|
||||
|
||||
/**
|
||||
* @brief Describes an enumeration
|
||||
* enum_name() returns the name of an enum value, or NULL if invalid.
|
||||
*/
|
||||
typedef const struct enum_names enum_names;
|
||||
|
||||
struct enum_names {
|
||||
unsigned long en_first; /* first value in range */
|
||||
unsigned long en_last; /* last value in range (inclusive) */
|
||||
const char *const *en_names;
|
||||
enum_names *en_next_range; /* descriptor of next range */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns the name of an enum value, or NULL if invalid
|
||||
*/
|
||||
const char *enum_name(enum_names *ed, unsigned long val);
|
||||
|
||||
#endif /*DEFINITIONS_H_*/
|
||||
|
|
|
@ -109,23 +109,6 @@ enum status_t {
|
|||
CREATED,
|
||||
};
|
||||
|
||||
/**
|
||||
* RFC 2459 CRL reason codes
|
||||
*/
|
||||
|
||||
/* TODO extern enum_names crl_reason_names; */
|
||||
|
||||
typedef enum {
|
||||
REASON_UNSPECIFIED = 0,
|
||||
REASON_KEY_COMPROMISE = 1,
|
||||
REASON_CA_COMPROMISE = 2,
|
||||
REASON_AFFILIATION_CHANGED = 3,
|
||||
REASON_SUPERSEDED = 4,
|
||||
REASON_CESSATION_OF_OPERATON = 5,
|
||||
REASON_CERTIFICATE_HOLD = 6,
|
||||
REASON_REMOVE_FROM_CRL = 8
|
||||
} crl_reason_t;
|
||||
|
||||
/**
|
||||
* String mappings for type status_t.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue