pluto and scepclient now use the x509 plugin for certificates

This commit is contained in:
Andreas Steffen
2009-09-27 23:09:30 +02:00
parent 727b0f11e2
commit 0eff9f6539
27 changed files with 1136 additions and 1640 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
ipsec_PROGRAMS = scepclient
scepclient_SOURCES = scepclient.c pkcs10.c pkcs10.h scep.c scep.h loglite.c
scepclient_SOURCES = scepclient.c scep.c scep.h loglite.c
PLUTODIR=$(top_srcdir)/src/pluto
OPENACDIR=$(top_srcdir)/src/openac
+15 -19
View File
@@ -45,15 +45,14 @@ static const chunk_t ASN1_extensionRequest_oid = chunk_from_chars(
);
/**
* @brief Adds a subjectAltName in DER-coded form to a linked list
* Adds a subjectAltName in DER-coded form to a linked list
*
* @param[in,out] subjectAltNames head of the linked list of subjectAltNames
* @param[in] kind type of the subjectAltName (which is a generalName)
* @param[in] value value of the subjectAltName as an ASCII string
* @param[in] subjectAltNames linked list of subjectAltNames
* @param[in] kind type of the subjectAltName (which is a generalName)
* @param[in] value value of the subjectAltName as an ASCII string
*/
void
pkcs10_add_subjectAltName(generalName_t **subjectAltNames, generalNames_t kind
, char *value)
void pkcs10_add_subjectAltName(linked_list_t *subjectAltNames,
generalNames_t kind, char *value)
{
generalName_t *gn;
asn1_t asn1_type = ASN1_EOC;
@@ -96,16 +95,15 @@ pkcs10_add_subjectAltName(generalName_t **subjectAltNames, generalNames_t kind
}
/**
* @brief Builds the requestInfoAttributes of the certificationRequestInfo-field
* Builds the requestInfoAttributes of the certificationRequestInfo-field
*
* challenge password ans subjectAltNames are only included,
* when avaiable in given #pkcs10_t structure
*
* @param[in] pkcs10 Pointer to a #pkcs10_t structure
* @return 1 if succeeded, 0 otherwise
* @return 1 if succeeded, 0 otherwise
*/
static chunk_t
build_req_info_attributes(pkcs10_t* pkcs10)
static chunk_t build_req_info_attributes(pkcs10_t* pkcs10)
{
chunk_t subjectAltNames = chunk_empty;
@@ -143,13 +141,12 @@ build_req_info_attributes(pkcs10_t* pkcs10)
}
/**
* @brief Builds a DER-code pkcs#10 certificate request
* Builds a DER-code pkcs#10 certificate request
*
* @param[in] pkcs10 pointer to a pkcs10_t struct
* @return DER-code pkcs10 request
*/
static chunk_t
pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
static chunk_t pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
{
chunk_t key = chunk_empty;
@@ -175,7 +172,7 @@ pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
}
/**
* @brief Creates a pkcs#10 certificate request object
* Creates a pkcs#10 certificate request object
*
* To create a certificate request, the RSA key and the
* names to be included as subject in the certificate request
@@ -190,7 +187,7 @@ pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
*/
pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
chunk_t subject, chunk_t challengePassword,
generalName_t *subjectAltNames, int signature_alg)
linked_list_t *subjectAltNames, int signature_alg)
{
pkcs10_t *pkcs10 = malloc_thing(pkcs10_t);
@@ -205,12 +202,11 @@ pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
}
/**
* @brief Frees the resources used by an #pkcs10_t object
* Frees the resources used by an #pkcs10_t object
*
* @param[in] pkcs10 #pkcs10_t to free
*/
void
pkcs10_free(pkcs10_t *pkcs10)
void pkcs10_free(pkcs10_t *pkcs10)
{
if (pkcs10 != NULL)
{
+4 -3
View File
@@ -23,6 +23,7 @@
#ifndef _PKCS10_H
#define _PKCS10_H
#include <utils/linked_list.h>
#include <credentials/keys/private_key.h>
#include <credentials/keys/public_key.h>
@@ -45,16 +46,16 @@ struct pkcs10_struct {
chunk_t request;
chunk_t subject;
chunk_t challengePassword;
generalName_t *subjectAltNames;
linked_list_t *subjectAltNames;
};
extern const pkcs10_t empty_pkcs10;
extern void pkcs10_add_subjectAltName(generalName_t **subjectAltNames,
extern void pkcs10_add_subjectAltName(linked_list_t *subjectAltNames,
generalNames_t kind, char *value);
extern pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
chunk_t subject, chunk_t challengePassword,
generalName_t *subjectAltNames, int signature_alg);
linked_list_t *subjectAltNames, int signature_alg);
extern void pkcs10_free(pkcs10_t *pkcs10);
#endif /* _PKCS10_H */
+3 -3
View File
@@ -370,8 +370,8 @@ chunk_t scep_senderNonce_attribute(void)
* Builds a pkcs7 enveloped and signed scep request
*/
chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
const x509cert_t *enc_cert, int enc_alg,
const x509cert_t *signer_cert, int digest_alg,
certificate_t *enc_cert, int enc_alg,
certificate_t *signer_cert, int digest_alg,
private_key_t *private_key)
{
chunk_t envelopedData, attributes, request;
@@ -525,7 +525,7 @@ bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
}
err_t scep_parse_response(chunk_t response, chunk_t transID, contentInfo_t *data,
scep_attributes_t *attrs, x509cert_t *signer_cert)
scep_attributes_t *attrs, certificate_t *signer_cert)
{
chunk_t attributes;
+5 -3
View File
@@ -23,6 +23,8 @@
#ifndef _SCEP_H
#define _SCEP_H
#include <credentials/certificates/certificate.h>
#include "../pluto/defs.h"
#include "../pluto/pkcs7.h"
@@ -81,13 +83,13 @@ extern chunk_t scep_transId_attribute(chunk_t transaction_id);
extern chunk_t scep_messageType_attribute(scep_msg_t m);
extern chunk_t scep_senderNonce_attribute(void);
extern chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
const x509cert_t *enc_cert, int enc_alg,
const x509cert_t *signer_cert, int digest_alg,
certificate_t *enc_cert, int enc_alg,
certificate_t *signer_cert, int digest_alg,
private_key_t *private_key);
extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
bool http_get_request, chunk_t *response);
extern err_t scep_parse_response(chunk_t response, chunk_t transID,
contentInfo_t *data, scep_attributes_t *attrs,
x509cert_t *signer_cert);
certificate_t *signer_cert);
#endif /* _SCEP_H */
+122 -98
View File
@@ -41,10 +41,15 @@
#include <asn1/oid.h>
#include <utils/optionsfrom.h>
#include <utils/enumerator.h>
#include <utils/linked_list.h>
#include <crypto/hashers/hasher.h>
#include <crypto/crypters/crypter.h>
#include <crypto/proposal/proposal_keywords.h>
#include <credentials/keys/private_key.h>
#include <credentials/keys/public_key.h>
#include <credentials/certificates/certificate.h>
#include <credentials/certificates/x509.h>
#include <credentials/certificates/pkcs10.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
@@ -52,7 +57,6 @@
#include "../pluto/pkcs7.h"
#include "../pluto/certs.h"
#include "pkcs10.h"
#include "scep.h"
/*
@@ -121,26 +125,27 @@ options_t *options;
* Global variables
*/
private_key_t *private_key = NULL;
public_key_t *public_key = NULL;
chunk_t pkcs1;
chunk_t pkcs7;
chunk_t subject;
chunk_t challengePassword;
chunk_t serialNumber;
chunk_t transID;
chunk_t fingerprint;
chunk_t encoding;
chunk_t pkcs10_encoding;
chunk_t issuerAndSubject;
chunk_t getCertInitial;
chunk_t scep_response;
cert_t cert;
x509cert_t *x509_signer = NULL;
x509cert_t *x509_ca_enc = NULL;
x509cert_t *x509_ca_sig = NULL;
generalName_t *subjectAltNames = NULL;
pkcs10_t *pkcs10 = NULL;
linked_list_t *subjectAltNames;
identification_t *subject = NULL;
private_key_t *private_key = NULL;
public_key_t *public_key = NULL;
certificate_t *x509_signer = NULL;
certificate_t *x509_ca_enc = NULL;
certificate_t *x509_ca_sig = NULL;
certificate_t *pkcs10_req = NULL;
/**
* @brief exit scepclient
@@ -152,27 +157,25 @@ exit_scepclient(err_t message, ...)
{
int status = 0;
DESTROY_IF(subject);
DESTROY_IF(private_key);
DESTROY_IF(public_key);
DESTROY_IF(x509_signer);
DESTROY_IF(x509_ca_enc);
DESTROY_IF(x509_ca_sig);
DESTROY_IF(pkcs10_req);
subjectAltNames->destroy_offset(subjectAltNames,
offsetof(identification_t, destroy));
free(pkcs1.ptr);
free(pkcs7.ptr);
free(subject.ptr);
free(serialNumber.ptr);
free(transID.ptr);
free(fingerprint.ptr);
free(encoding.ptr);
free(pkcs10_encoding.ptr);
free(issuerAndSubject.ptr);
free(getCertInitial.ptr);
free(scep_response.ptr);
free_generalNames(subjectAltNames, TRUE);
if (x509_signer != NULL)
{
x509_signer->subjectAltName = NULL;
}
free_x509cert(x509_signer);
free_x509cert(x509_ca_enc);
free_x509cert(x509_ca_sig);
pkcs10_free(pkcs10);
options->destroy(options);
/* print any error message to stderr */
@@ -357,8 +360,8 @@ int main(int argc, char **argv)
/* digest algorithm used by pkcs7, default is SHA-1 */
int pkcs7_digest_alg = OID_SHA1;
/* signature algorithm used by pkcs10, default is SHA-1 with RSA encryption */
int pkcs10_signature_alg = OID_SHA1;
/* signature algorithm used by pkcs10, default is SHA-1 */
hash_algorithm_t pkcs10_signature_alg = HASH_SHA1;
/* URL of the SCEP-Server */
char *scep_url = NULL;
@@ -374,18 +377,6 @@ int main(int argc, char **argv)
err_t ugh = NULL;
/* initialize global variables */
pkcs1 = chunk_empty;
pkcs7 = chunk_empty;
serialNumber = chunk_empty;
transID = chunk_empty;
fingerprint = chunk_empty;
issuerAndSubject = chunk_empty;
challengePassword = chunk_empty;
getCertInitial = chunk_empty;
scep_response = chunk_empty;
log_to_stderr = TRUE;
/* initialize library */
if (!library_init(NULL))
{
@@ -400,8 +391,21 @@ int main(int argc, char **argv)
exit(SS_RC_DAEMON_INTEGRITY);
}
/* initialize optionsfrom */
options = options_create();
/* initialize global variables */
pkcs1 = chunk_empty;
pkcs7 = chunk_empty;
serialNumber = chunk_empty;
transID = chunk_empty;
fingerprint = chunk_empty;
encoding = chunk_empty;
pkcs10_encoding = chunk_empty;
issuerAndSubject = chunk_empty;
challengePassword = chunk_empty;
getCertInitial = chunk_empty;
scep_response = chunk_empty;
subjectAltNames = linked_list_create();
options = options_create();
log_to_stderr = TRUE;
for (;;)
{
@@ -614,7 +618,6 @@ int main(int argc, char **argv)
case 's': /* --subjectAltName */
{
generalNames_t kind;
char *value = strstr(optarg, "=");
if (value)
@@ -625,25 +628,19 @@ int main(int argc, char **argv)
value++;
}
if (strcaseeq("email", optarg))
if (strcaseeq("email", optarg) ||
strcaseeq("dns", optarg) ||
strcaseeq("ip", optarg))
{
kind = GN_RFC822_NAME;
}
else if (strcaseeq("dns", optarg))
{
kind = GN_DNS_NAME;
}
else if (strcaseeq("ip", optarg))
{
kind = GN_IP_ADDRESS;
subjectAltNames->insert_last(subjectAltNames,
identification_create_from_string(value));
continue;
}
else
{
usage("invalid --subjectAltName type");
continue;
}
pkcs10_add_subjectAltName(&subjectAltNames, kind, value);
continue;
}
case 'p': /* --password */
@@ -831,11 +828,6 @@ int main(int argc, char **argv)
}
else
{
char buf[IDTOA_BUF];
chunk_t dn = chunk_empty;
dn.ptr = buf;
if (distinguishedName == NULL)
{
char buf[BUF_LEN];
@@ -853,21 +845,29 @@ int main(int argc, char **argv)
DBG(DBG_CONTROL,
DBG_log("dn: '%s'", distinguishedName);
)
ugh = atodn(distinguishedName, &dn);
if (ugh != NULL)
subject = identification_create_from_string(distinguishedName);
if (subject->get_type(subject) != ID_DER_ASN1_DN)
{
exit_scepclient(ugh);
exit_scepclient("parsing of distinguished name failed");
}
subject = chunk_clone(dn);
DBG(DBG_CONTROL,
DBG_log("building pkcs10 object:")
)
pkcs10 = pkcs10_build(private_key, public_key, subject,
challengePassword, subjectAltNames,
pkcs10_signature_alg);
fingerprint = scep_generate_pkcs10_fingerprint(pkcs10->request);
pkcs10_req = lib->creds->create(lib->creds, CRED_CERTIFICATE,
CERT_PKCS10_REQUEST,
BUILD_SIGNING_KEY, private_key,
BUILD_SUBJECT, subject,
BUILD_SUBJECT_ALTNAMES, subjectAltNames,
BUILD_PASSPHRASE, challengePassword,
BUILD_DIGEST_ALG, pkcs10_signature_alg,
BUILD_END);
if (!pkcs10_req)
{
exit_scepclient("generating pkcs10 request failed");
}
pkcs10_encoding = pkcs10_req->get_encoding(pkcs10_req);
fingerprint = scep_generate_pkcs10_fingerprint(pkcs10_encoding);
plog(" fingerprint: %s", fingerprint.ptr);
}
@@ -878,9 +878,10 @@ int main(int argc, char **argv)
{
char *path = concatenate_paths(REQ_PATH, file_out_pkcs10);
if (!chunk_write(pkcs10->request, path, "pkcs10", 0022, force))
if (!chunk_write(pkcs10_encoding, path, "pkcs10", 0022, force))
{
exit_scepclient("could not write pkcs10 file '%s'", path);
}
filetype_out &= ~PKCS10; /* delete PKCS10 flag */
}
@@ -901,8 +902,9 @@ int main(int argc, char **argv)
)
if (!private_key->get_encoding(private_key, KEY_PRIV_ASN1_DER, &pkcs1) ||
!chunk_write(pkcs1, path, "pkcs1", 0066, force))
{
exit_scepclient("could not write pkcs1 file '%s'", path);
}
filetype_out &= ~PKCS1; /* delete PKCS1 flag */
}
@@ -914,19 +916,23 @@ int main(int argc, char **argv)
scep_generate_transaction_id(public_key, &transID, &serialNumber);
plog(" transaction ID: %.*s", (int)transID.len, transID.ptr);
notBefore = notBefore ? notBefore : time(NULL);
notAfter = notAfter ? notAfter : (notBefore + validity);
/* generate a self-signed X.509 certificate */
x509_signer = malloc_thing(x509cert_t);
*x509_signer = empty_x509cert;
x509_signer->serialNumber = serialNumber;
x509_signer->sigAlg = OID_SHA1_WITH_RSA;
x509_signer->issuer = subject;
x509_signer->notBefore = (notBefore)? notBefore
: time(NULL);
x509_signer->notAfter = (notAfter)? notAfter
: x509_signer->notBefore + validity;
x509_signer->subject = subject;
x509_signer->subjectAltName = subjectAltNames;
build_x509cert(x509_signer, public_key, private_key);
x509_signer = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, private_key,
BUILD_PUBLIC_KEY, public_key,
BUILD_SUBJECT, subject,
BUILD_NOT_BEFORE_TIME, notBefore,
BUILD_NOT_AFTER_TIME, notAfter,
BUILD_SERIAL, serialNumber,
BUILD_SUBJECT_ALTNAMES, subjectAltNames,
BUILD_END);
if (!x509_signer)
{
exit_scepclient("generating certificate failed");
}
/*
* output of self-signed X.509 certificate file
@@ -935,9 +941,16 @@ int main(int argc, char **argv)
{
char *path = concatenate_paths(HOST_CERT_PATH, file_out_cert_self);
if (!chunk_write(x509_signer->certificate, path, "self-signed cert", 0022, force))
encoding = x509_signer->get_encoding(x509_signer);
if (!encoding.ptr)
{
exit_scepclient("encoding certificate failed");
}
if (!chunk_write(encoding, path, "self-signed cert", 0022, force))
{
exit_scepclient("could not write self-signed cert file '%s'", path);
;
}
chunk_free(&encoding);
filetype_out &= ~CERT_SELF; /* delete CERT_SELF flag */
}
@@ -951,13 +964,13 @@ int main(int argc, char **argv)
*/
{
char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_enc);
cert_t cert;
if (!load_cert(path, "encryption cacert", &cert))
x509_ca_enc = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, path, BUILD_END);
if (!x509_ca_enc)
{
exit_scepclient("could not load encryption cacert file '%s'", path);
}
x509_ca_enc = cert.u.x509;
}
/*
@@ -978,10 +991,10 @@ int main(int argc, char **argv)
DBG(DBG_CONTROL,
DBG_log("building pkcs7 request")
)
pkcs7 = scep_build_request(pkcs10->request
, transID, SCEP_PKCSReq_MSG
, x509_ca_enc, pkcs7_symmetric_cipher
, x509_signer, pkcs7_digest_alg, private_key);
pkcs7 = scep_build_request(pkcs10_encoding,
transID, SCEP_PKCSReq_MSG,
x509_ca_enc, pkcs7_symmetric_cipher,
x509_signer, pkcs7_digest_alg, private_key);
}
/*
@@ -1008,7 +1021,6 @@ int main(int argc, char **argv)
if (filetype_out & CERT)
{
char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
cert_t cert;
time_t poll_start = 0;
x509cert_t *certs = NULL;
@@ -1017,9 +1029,12 @@ int main(int argc, char **argv)
contentInfo_t data = empty_contentInfo;
scep_attributes_t attrs = empty_scep_attributes;
if (!load_cert(path, "signature cacert", &cert))
x509_ca_sig = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, path, BUILD_END);
if (!x509_ca_sig)
{
exit_scepclient("could not load signature cacert file '%s'", path);
x509_ca_sig = cert.u.x509;
}
if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION,
http_get_request, &scep_response))
@@ -1036,12 +1051,14 @@ int main(int argc, char **argv)
/* in case of manual mode, we are going into a polling loop */
if (attrs.pkiStatus == SCEP_PENDING)
{
identification_t *issuer = x509_ca_sig->get_subject(x509_ca_sig);
plog(" scep request pending, polling every %d seconds"
, poll_interval);
poll_start = time_monotonic(NULL);
issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc"
, x509_ca_sig->subject
, subject);
issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc",
issuer->get_encoding(issuer),
subject);
}
while (attrs.pkiStatus == SCEP_PENDING)
{
@@ -1110,13 +1127,20 @@ int main(int argc, char **argv)
{
bool stored = FALSE;
x509cert_t *cert = certs;
x509_t *x509 = (x509_t*)cert->cert;
if (!cert->isCA)
if (!(x509->get_flags(x509) & X509_CA))
{
if (stored)
{
exit_scepclient("multiple certs received, only first stored");
if (!chunk_write(cert->certificate, path, "requested cert", 0022, force))
}
encoding = cert->cert->get_encoding(cert->cert);
if (!chunk_write(encoding, path, "requested cert", 0022, force))
{
exit_scepclient("could not write cert file '%s'", path);
}
chunk_free(&encoding);
stored = TRUE;
}
certs = certs->next;