aboutsummaryrefslogtreecommitdiffstats
path: root/src/scepclient
diff options
context:
space:
mode:
Diffstat (limited to 'src/scepclient')
-rw-r--r--src/scepclient/Makefile.am2
-rw-r--r--src/scepclient/pkcs10.c34
-rw-r--r--src/scepclient/pkcs10.h7
-rw-r--r--src/scepclient/scep.c6
-rw-r--r--src/scepclient/scep.h8
-rw-r--r--src/scepclient/scepclient.c220
6 files changed, 150 insertions, 127 deletions
diff --git a/src/scepclient/Makefile.am b/src/scepclient/Makefile.am
index 88481fa15..36a38a628 100644
--- a/src/scepclient/Makefile.am
+++ b/src/scepclient/Makefile.am
@@ -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
diff --git a/src/scepclient/pkcs10.c b/src/scepclient/pkcs10.c
index 95fd768b7..04196777c 100644
--- a/src/scepclient/pkcs10.c
+++ b/src/scepclient/pkcs10.c
@@ -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)
{
diff --git a/src/scepclient/pkcs10.h b/src/scepclient/pkcs10.h
index e10a3ef59..a4d892576 100644
--- a/src/scepclient/pkcs10.h
+++ b/src/scepclient/pkcs10.h
@@ -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 */
diff --git a/src/scepclient/scep.c b/src/scepclient/scep.c
index 86fd5656e..598705636 100644
--- a/src/scepclient/scep.c
+++ b/src/scepclient/scep.c
@@ -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;
diff --git a/src/scepclient/scep.h b/src/scepclient/scep.h
index e044f0b1c..f64c6b1cc 100644
--- a/src/scepclient/scep.h
+++ b/src/scepclient/scep.h
@@ -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 */
diff --git a/src/scepclient/scepclient.c b/src/scepclient/scepclient.c
index 34b98547e..91f89cc62 100644
--- a/src/scepclient/scepclient.c
+++ b/src/scepclient/scepclient.c
@@ -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))
- {
- kind = GN_RFC822_NAME;
- }
- else if (strcaseeq("dns", optarg))
- {
- kind = GN_DNS_NAME;
- }
- else if (strcaseeq("ip", optarg))
+ if (strcaseeq("email", optarg) ||
+ strcaseeq("dns", optarg) ||
+ 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;