mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-08 00:02:03 -04:00
scepclient: Some code cleanup.
This commit is contained in:
parent
07f0abd7ac
commit
25924d3e45
@ -1,10 +1,3 @@
|
|||||||
/**
|
|
||||||
* @file scep.c
|
|
||||||
* @brief SCEP specific functions
|
|
||||||
*
|
|
||||||
* Contains functions to build SCEP request's and to parse SCEP reply's.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@ -39,16 +32,6 @@
|
|||||||
|
|
||||||
#include "scep.h"
|
#include "scep.h"
|
||||||
|
|
||||||
static const chunk_t ASN1_messageType_oid = chunk_from_chars(
|
|
||||||
0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x02
|
|
||||||
);
|
|
||||||
static const chunk_t ASN1_senderNonce_oid = chunk_from_chars(
|
|
||||||
0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x05
|
|
||||||
);
|
|
||||||
static const chunk_t ASN1_transId_oid = chunk_from_chars(
|
|
||||||
0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x07
|
|
||||||
);
|
|
||||||
|
|
||||||
static const char *pkiStatus_values[] = { "0", "2", "3" };
|
static const char *pkiStatus_values[] = { "0", "2", "3" };
|
||||||
|
|
||||||
static const char *pkiStatus_names[] = {
|
static const char *pkiStatus_names[] = {
|
||||||
@ -112,61 +95,65 @@ static bool extract_attribute(int oid, chunk_t object, u_int level,
|
|||||||
|
|
||||||
switch (oid)
|
switch (oid)
|
||||||
{
|
{
|
||||||
case OID_PKCS9_CONTENT_TYPE:
|
case OID_PKCS9_CONTENT_TYPE:
|
||||||
type = ASN1_OID;
|
type = ASN1_OID;
|
||||||
name = "contentType";
|
name = "contentType";
|
||||||
break;
|
break;
|
||||||
case OID_PKCS9_SIGNING_TIME:
|
case OID_PKCS9_SIGNING_TIME:
|
||||||
type = ASN1_UTCTIME;
|
type = ASN1_UTCTIME;
|
||||||
name = "signingTime";
|
name = "signingTime";
|
||||||
break;
|
break;
|
||||||
case OID_PKCS9_MESSAGE_DIGEST:
|
case OID_PKCS9_MESSAGE_DIGEST:
|
||||||
type = ASN1_OCTET_STRING;
|
type = ASN1_OCTET_STRING;
|
||||||
name = "messageDigest";
|
name = "messageDigest";
|
||||||
break;
|
break;
|
||||||
case OID_PKI_MESSAGE_TYPE:
|
case OID_PKI_MESSAGE_TYPE:
|
||||||
type = ASN1_PRINTABLESTRING;
|
type = ASN1_PRINTABLESTRING;
|
||||||
name = "messageType";
|
name = "messageType";
|
||||||
break;
|
break;
|
||||||
case OID_PKI_STATUS:
|
case OID_PKI_STATUS:
|
||||||
type = ASN1_PRINTABLESTRING;
|
type = ASN1_PRINTABLESTRING;
|
||||||
name = "pkiStatus";
|
name = "pkiStatus";
|
||||||
break;
|
break;
|
||||||
case OID_PKI_FAIL_INFO:
|
case OID_PKI_FAIL_INFO:
|
||||||
type = ASN1_PRINTABLESTRING;
|
type = ASN1_PRINTABLESTRING;
|
||||||
name = "failInfo";
|
name = "failInfo";
|
||||||
break;
|
break;
|
||||||
case OID_PKI_SENDER_NONCE:
|
case OID_PKI_SENDER_NONCE:
|
||||||
type = ASN1_OCTET_STRING;
|
type = ASN1_OCTET_STRING;
|
||||||
name = "senderNonce";
|
name = "senderNonce";
|
||||||
break;
|
break;
|
||||||
case OID_PKI_RECIPIENT_NONCE:
|
case OID_PKI_RECIPIENT_NONCE:
|
||||||
type = ASN1_OCTET_STRING;
|
type = ASN1_OCTET_STRING;
|
||||||
name = "recipientNonce";
|
name = "recipientNonce";
|
||||||
break;
|
break;
|
||||||
case OID_PKI_TRANS_ID:
|
case OID_PKI_TRANS_ID:
|
||||||
type = ASN1_PRINTABLESTRING;
|
type = ASN1_PRINTABLESTRING;
|
||||||
name = "transID";
|
name = "transID";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == ASN1_EOC)
|
if (type == ASN1_EOC)
|
||||||
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!asn1_parse_simple_object(&object, type, level+1, name))
|
if (!asn1_parse_simple_object(&object, type, level+1, name))
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (oid)
|
switch (oid)
|
||||||
{
|
{
|
||||||
case OID_PKCS9_CONTENT_TYPE:
|
case OID_PKCS9_CONTENT_TYPE:
|
||||||
break;
|
break;
|
||||||
case OID_PKCS9_SIGNING_TIME:
|
case OID_PKCS9_SIGNING_TIME:
|
||||||
break;
|
break;
|
||||||
case OID_PKCS9_MESSAGE_DIGEST:
|
case OID_PKCS9_MESSAGE_DIGEST:
|
||||||
break;
|
break;
|
||||||
case OID_PKI_MESSAGE_TYPE:
|
case OID_PKI_MESSAGE_TYPE:
|
||||||
{
|
{
|
||||||
scep_msg_t m;
|
scep_msg_t m;
|
||||||
|
|
||||||
@ -178,39 +165,46 @@ static bool extract_attribute(int oid, chunk_t object, u_int level,
|
|||||||
DBG(DBG_CONTROL,
|
DBG(DBG_CONTROL,
|
||||||
DBG_log("messageType: %s", msgType_names[attrs->msgType])
|
DBG_log("messageType: %s", msgType_names[attrs->msgType])
|
||||||
)
|
)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case OID_PKI_STATUS:
|
||||||
case OID_PKI_STATUS:
|
|
||||||
{
|
{
|
||||||
pkiStatus_t s;
|
pkiStatus_t s;
|
||||||
|
|
||||||
for (s = SCEP_SUCCESS; s < SCEP_UNKNOWN; s++)
|
for (s = SCEP_SUCCESS; s < SCEP_UNKNOWN; s++)
|
||||||
{
|
{
|
||||||
if (strncmp(pkiStatus_values[s], object.ptr, object.len) == 0)
|
if (strncmp(pkiStatus_values[s], object.ptr, object.len) == 0)
|
||||||
|
{
|
||||||
attrs->pkiStatus = s;
|
attrs->pkiStatus = s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DBG(DBG_CONTROL,
|
DBG(DBG_CONTROL,
|
||||||
DBG_log("pkiStatus: %s", pkiStatus_names[attrs->pkiStatus])
|
DBG_log("pkiStatus: %s", pkiStatus_names[attrs->pkiStatus])
|
||||||
)
|
)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case OID_PKI_FAIL_INFO:
|
||||||
case OID_PKI_FAIL_INFO:
|
|
||||||
if (object.len == 1
|
|
||||||
&& *object.ptr >= '0' && *object.ptr <= '4')
|
|
||||||
{
|
{
|
||||||
attrs->failInfo = (failInfo_t)(*object.ptr - '0');
|
if (object.len == 1 &&
|
||||||
|
*object.ptr >= '0' && *object.ptr <= '4')
|
||||||
|
{
|
||||||
|
attrs->failInfo = (failInfo_t)(*object.ptr - '0');
|
||||||
|
}
|
||||||
|
if (attrs->failInfo != SCEP_unknown_REASON)
|
||||||
|
{
|
||||||
|
plog("failInfo: %s", failInfo_reasons[attrs->failInfo]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (attrs->failInfo != SCEP_unknown_REASON)
|
case OID_PKI_SENDER_NONCE:
|
||||||
plog("failInfo: %s", failInfo_reasons[attrs->failInfo]);
|
attrs->senderNonce = object;
|
||||||
break;
|
break;
|
||||||
case OID_PKI_SENDER_NONCE:
|
case OID_PKI_RECIPIENT_NONCE:
|
||||||
attrs->senderNonce = object;
|
attrs->recipientNonce = object;
|
||||||
break;
|
break;
|
||||||
case OID_PKI_RECIPIENT_NONCE:
|
case OID_PKI_TRANS_ID:
|
||||||
attrs->recipientNonce = object;
|
attrs->transID = object;
|
||||||
break;
|
break;
|
||||||
case OID_PKI_TRANS_ID:
|
|
||||||
attrs->transID = object;
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -235,13 +229,16 @@ bool parse_attributes(chunk_t blob, scep_attributes_t *attrs)
|
|||||||
{
|
{
|
||||||
switch (objectID)
|
switch (objectID)
|
||||||
{
|
{
|
||||||
case ATTRIBUTE_OBJ_TYPE:
|
case ATTRIBUTE_OBJ_TYPE:
|
||||||
oid = asn1_known_oid(object);
|
oid = asn1_known_oid(object);
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_OBJ_VALUE:
|
case ATTRIBUTE_OBJ_VALUE:
|
||||||
if (!extract_attribute(oid, object, parser->get_level(parser), attrs))
|
|
||||||
{
|
{
|
||||||
goto end;
|
if (!extract_attribute(oid, object, parser->get_level(parser), attrs))
|
||||||
|
{
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,12 +315,10 @@ void scep_generate_transaction_id(public_key_t *key, chunk_t *transID,
|
|||||||
*/
|
*/
|
||||||
chunk_t scep_transId_attribute(chunk_t transID)
|
chunk_t scep_transId_attribute(chunk_t transID)
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
return asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||||
, ASN1_transId_oid
|
asn1_build_known_oid(OID_PKI_TRANS_ID),
|
||||||
, asn1_wrap(ASN1_SET, "m"
|
asn1_wrap(ASN1_SET, "m",
|
||||||
, asn1_simple_object(ASN1_PRINTABLESTRING, transID)
|
asn1_simple_object(ASN1_PRINTABLESTRING, transID)));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -336,12 +331,10 @@ chunk_t scep_messageType_attribute(scep_msg_t m)
|
|||||||
strlen(msgType_values[m])
|
strlen(msgType_values[m])
|
||||||
};
|
};
|
||||||
|
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
return asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
, ASN1_messageType_oid
|
asn1_build_known_oid(OID_PKI_MESSAGE_TYPE),
|
||||||
, asn1_wrap(ASN1_SET, "m"
|
asn1_wrap(ASN1_SET, "m",
|
||||||
, asn1_simple_object(ASN1_PRINTABLESTRING, msgType)
|
asn1_simple_object(ASN1_PRINTABLESTRING, msgType)));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -358,12 +351,10 @@ chunk_t scep_senderNonce_attribute(void)
|
|||||||
rng->get_bytes(rng, nonce_len, nonce_buf);
|
rng->get_bytes(rng, nonce_len, nonce_buf);
|
||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
|
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
return asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||||
, ASN1_senderNonce_oid
|
asn1_build_known_oid(OID_PKI_SENDER_NONCE),
|
||||||
, asn1_wrap(ASN1_SET, "m"
|
asn1_wrap(ASN1_SET, "m",
|
||||||
, asn1_simple_object(ASN1_OCTET_STRING, senderNonce)
|
asn1_simple_object(ASN1_OCTET_STRING, senderNonce)));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -378,16 +369,15 @@ chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
|
|||||||
|
|
||||||
envelopedData = pkcs7_build_envelopedData(data, enc_cert, enc_alg);
|
envelopedData = pkcs7_build_envelopedData(data, enc_cert, enc_alg);
|
||||||
|
|
||||||
attributes = asn1_wrap(ASN1_SET, "mmmmm"
|
attributes = asn1_wrap(ASN1_SET, "mmmmm",
|
||||||
, pkcs7_contentType_attribute()
|
pkcs7_contentType_attribute(),
|
||||||
, pkcs7_messageDigest_attribute(envelopedData
|
pkcs7_messageDigest_attribute(envelopedData, digest_alg),
|
||||||
, digest_alg)
|
scep_transId_attribute(transID),
|
||||||
, scep_transId_attribute(transID)
|
scep_messageType_attribute(msg),
|
||||||
, scep_messageType_attribute(msg)
|
scep_senderNonce_attribute());
|
||||||
, scep_senderNonce_attribute());
|
|
||||||
|
|
||||||
request = pkcs7_build_signedData(envelopedData, attributes
|
request = pkcs7_build_signedData(envelopedData, attributes,
|
||||||
, signer_cert, digest_alg, private_key);
|
signer_cert, digest_alg, private_key);
|
||||||
free(envelopedData.ptr);
|
free(envelopedData.ptr);
|
||||||
free(attributes.ptr);
|
free(attributes.ptr);
|
||||||
return request;
|
return request;
|
||||||
@ -420,7 +410,9 @@ static char* escape_http_request(chunk_t req)
|
|||||||
while (*p1 != '\0')
|
while (*p1 != '\0')
|
||||||
{
|
{
|
||||||
if (*p1++ == '+')
|
if (*p1++ == '+')
|
||||||
|
{
|
||||||
plus++;
|
plus++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
escaped_req = malloc(len + 3*(lines + plus));
|
escaped_req = malloc(len + 3*(lines + plus));
|
||||||
@ -513,8 +505,8 @@ bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
|
|||||||
/* form complete url */
|
/* form complete url */
|
||||||
len = strlen(url) + 32 + strlen(operation) + 1;
|
len = strlen(url) + 32 + strlen(operation) + 1;
|
||||||
complete_url = malloc(len);
|
complete_url = malloc(len);
|
||||||
snprintf(complete_url, len, "%s?operation=%s&message=CAIdentifier"
|
snprintf(complete_url, len, "%s?operation=%s&message=CAIdentifier",
|
||||||
, url, operation);
|
url, operation);
|
||||||
|
|
||||||
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
||||||
FETCH_END);
|
FETCH_END);
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
/**
|
|
||||||
* @file scep.h
|
|
||||||
* @brief SCEP specific functions
|
|
||||||
*
|
|
||||||
* Contains functions to build and parse SCEP requests and replies
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@ -74,22 +67,22 @@ typedef struct {
|
|||||||
|
|
||||||
extern const scep_attributes_t empty_scep_attributes;
|
extern const scep_attributes_t empty_scep_attributes;
|
||||||
|
|
||||||
extern bool parse_attributes(chunk_t blob, scep_attributes_t *attrs);
|
bool parse_attributes(chunk_t blob, scep_attributes_t *attrs);
|
||||||
extern void scep_generate_transaction_id(public_key_t *key,
|
void scep_generate_transaction_id(public_key_t *key,
|
||||||
chunk_t *transID,
|
chunk_t *transID,
|
||||||
chunk_t *serialNumber);
|
chunk_t *serialNumber);
|
||||||
extern chunk_t scep_generate_pkcs10_fingerprint(chunk_t pkcs10);
|
chunk_t scep_generate_pkcs10_fingerprint(chunk_t pkcs10);
|
||||||
extern chunk_t scep_transId_attribute(chunk_t transaction_id);
|
chunk_t scep_transId_attribute(chunk_t transaction_id);
|
||||||
extern chunk_t scep_messageType_attribute(scep_msg_t m);
|
chunk_t scep_messageType_attribute(scep_msg_t m);
|
||||||
extern chunk_t scep_senderNonce_attribute(void);
|
chunk_t scep_senderNonce_attribute(void);
|
||||||
extern chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
|
chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
|
||||||
certificate_t *enc_cert, int enc_alg,
|
certificate_t *enc_cert, int enc_alg,
|
||||||
certificate_t *signer_cert, int digest_alg,
|
certificate_t *signer_cert, int digest_alg,
|
||||||
private_key_t *private_key);
|
private_key_t *private_key);
|
||||||
extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
|
bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
|
||||||
bool http_get_request, chunk_t *response);
|
bool http_get_request, chunk_t *response);
|
||||||
extern err_t scep_parse_response(chunk_t response, chunk_t transID,
|
err_t scep_parse_response(chunk_t response, chunk_t transID,
|
||||||
contentInfo_t *data, scep_attributes_t *attrs,
|
contentInfo_t *data, scep_attributes_t *attrs,
|
||||||
certificate_t *signer_cert);
|
certificate_t *signer_cert);
|
||||||
|
|
||||||
#endif /* _SCEP_H */
|
#endif /* _SCEP_H */
|
||||||
|
@ -13,17 +13,6 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @file main.c
|
|
||||||
* @brief scepclient main program
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @mainpage SCEP for Linux strongSwan
|
|
||||||
*
|
|
||||||
* Documentation of SCEP for Linux StrongSwan
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -153,8 +142,7 @@ certificate_t *pkcs10_req = NULL;
|
|||||||
*
|
*
|
||||||
* @param status 0 = OK, 1 = general discomfort
|
* @param status 0 = OK, 1 = general discomfort
|
||||||
*/
|
*/
|
||||||
static void
|
static void exit_scepclient(err_t message, ...)
|
||||||
exit_scepclient(err_t message, ...)
|
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
@ -201,8 +189,7 @@ exit_scepclient(err_t message, ...)
|
|||||||
* @brief prints the program version and exits
|
* @brief prints the program version and exits
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void version(void)
|
||||||
version(void)
|
|
||||||
{
|
{
|
||||||
printf("scepclient %s\n", scepclient_version);
|
printf("scepclient %s\n", scepclient_version);
|
||||||
exit_scepclient(NULL);
|
exit_scepclient(NULL);
|
||||||
@ -214,8 +201,7 @@ version(void)
|
|||||||
* If message is set, program is exitet with 1 (error)
|
* If message is set, program is exitet with 1 (error)
|
||||||
* @param message message in case of an error
|
* @param message message in case of an error
|
||||||
*/
|
*/
|
||||||
static void
|
static void usage(const char *message)
|
||||||
usage(const char *message)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: scepclient\n"
|
"Usage: scepclient\n"
|
||||||
@ -429,20 +415,20 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case EOF: /* end of flags */
|
case EOF: /* end of flags */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h': /* --help */
|
case 'h': /* --help */
|
||||||
usage(NULL);
|
usage(NULL);
|
||||||
|
|
||||||
case 'v': /* --version */
|
case 'v': /* --version */
|
||||||
version();
|
version();
|
||||||
|
|
||||||
case 'q': /* --quiet */
|
case 'q': /* --quiet */
|
||||||
log_to_stderr = FALSE;
|
log_to_stderr = FALSE;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'i': /* --in <type> [= <filename>] */
|
case 'i': /* --in <type> [= <filename>] */
|
||||||
{
|
{
|
||||||
char *filename = strstr(optarg, "=");
|
char *filename = strstr(optarg, "=");
|
||||||
|
|
||||||
@ -478,7 +464,7 @@ int main(int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'o': /* --out <type> [= <filename>] */
|
case 'o': /* --out <type> [= <filename>] */
|
||||||
{
|
{
|
||||||
char *filename = strstr(optarg, "=");
|
char *filename = strstr(optarg, "=");
|
||||||
|
|
||||||
@ -532,18 +518,18 @@ int main(int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'f': /* --force */
|
case 'f': /* --force */
|
||||||
force = TRUE;
|
force = TRUE;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '+': /* --optionsfrom <filename> */
|
case '+': /* --optionsfrom <filename> */
|
||||||
if (!options->from(options, optarg, &argc, &argv, optind))
|
if (!options->from(options, optarg, &argc, &argv, optind))
|
||||||
{
|
{
|
||||||
exit_scepclient("optionsfrom failed");
|
exit_scepclient("optionsfrom failed");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'k': /* --keylength <length> */
|
case 'k': /* --keylength <length> */
|
||||||
{
|
{
|
||||||
div_t q;
|
div_t q;
|
||||||
|
|
||||||
@ -561,45 +547,56 @@ int main(int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'D': /* --days */
|
case 'D': /* --days */
|
||||||
if (optarg == NULL || !isdigit(optarg[0]))
|
if (optarg == NULL || !isdigit(optarg[0]))
|
||||||
usage("missing number of days");
|
{
|
||||||
{
|
usage("missing number of days");
|
||||||
char *endptr;
|
}
|
||||||
long days = strtol(optarg, &endptr, 0);
|
else
|
||||||
|
{
|
||||||
|
char *endptr;
|
||||||
|
long days = strtol(optarg, &endptr, 0);
|
||||||
|
|
||||||
if (*endptr != '\0' || endptr == optarg
|
if (*endptr != '\0' || endptr == optarg
|
||||||
|| days <= 0)
|
|| days <= 0)
|
||||||
usage("<days> must be a positive number");
|
usage("<days> must be a positive number");
|
||||||
validity = 24*3600*days;
|
validity = 24*3600*days;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'S': /* --startdate */
|
case 'S': /* --startdate */
|
||||||
if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
|
if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
|
||||||
usage("date format must be YYMMDDHHMMSSZ");
|
{
|
||||||
{
|
usage("date format must be YYMMDDHHMMSSZ");
|
||||||
chunk_t date = { optarg, 13 };
|
}
|
||||||
notBefore = asn1_to_time(&date, ASN1_UTCTIME);
|
else
|
||||||
}
|
{
|
||||||
continue;
|
chunk_t date = { optarg, 13 };
|
||||||
|
notBefore = asn1_to_time(&date, ASN1_UTCTIME);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
case 'E': /* --enddate */
|
case 'E': /* --enddate */
|
||||||
if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
|
if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
|
||||||
usage("date format must be YYMMDDHHMMSSZ");
|
{
|
||||||
{
|
usage("date format must be YYMMDDHHMMSSZ");
|
||||||
chunk_t date = { optarg, 13 };
|
}
|
||||||
notAfter = asn1_to_time(&date, ASN1_UTCTIME);
|
else
|
||||||
}
|
{
|
||||||
continue;
|
chunk_t date = { optarg, 13 };
|
||||||
|
notAfter = asn1_to_time(&date, ASN1_UTCTIME);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
case 'd': /* --dn */
|
case 'd': /* --dn */
|
||||||
if (distinguishedName)
|
if (distinguishedName)
|
||||||
usage("only one distinguished name allowed");
|
{
|
||||||
distinguishedName = optarg;
|
usage("only one distinguished name allowed");
|
||||||
continue;
|
}
|
||||||
|
distinguishedName = optarg;
|
||||||
|
continue;
|
||||||
|
|
||||||
case 's': /* --subjectAltName */
|
case 's': /* --subjectAltName */
|
||||||
{
|
{
|
||||||
char *value = strstr(optarg, "=");
|
char *value = strstr(optarg, "=");
|
||||||
|
|
||||||
@ -612,7 +609,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcaseeq("email", optarg) ||
|
if (strcaseeq("email", optarg) ||
|
||||||
strcaseeq("dns", optarg) ||
|
strcaseeq("dns", optarg) ||
|
||||||
strcaseeq("ip", optarg))
|
strcaseeq("ip", optarg))
|
||||||
{
|
{
|
||||||
subjectAltNames->insert_last(subjectAltNames,
|
subjectAltNames->insert_last(subjectAltNames,
|
||||||
@ -626,106 +623,107 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'p': /* --password */
|
case 'p': /* --password */
|
||||||
if (challengePassword.len > 0)
|
if (challengePassword.len > 0)
|
||||||
{
|
|
||||||
usage("only one challenge password allowed");
|
|
||||||
}
|
|
||||||
if (strcaseeq("%prompt", optarg))
|
|
||||||
{
|
|
||||||
printf("Challenge password: ");
|
|
||||||
if (fgets(challenge_password_buffer, sizeof(challenge_password_buffer)-1, stdin))
|
|
||||||
{
|
{
|
||||||
challengePassword.ptr = challenge_password_buffer;
|
usage("only one challenge password allowed");
|
||||||
/* discard the terminating '\n' from the input */
|
}
|
||||||
challengePassword.len = strlen(challenge_password_buffer) - 1;
|
if (strcaseeq("%prompt", optarg))
|
||||||
|
{
|
||||||
|
printf("Challenge password: ");
|
||||||
|
if (fgets(challenge_password_buffer,
|
||||||
|
sizeof(challenge_password_buffer) - 1, stdin))
|
||||||
|
{
|
||||||
|
challengePassword.ptr = challenge_password_buffer;
|
||||||
|
/* discard the terminating '\n' from the input */
|
||||||
|
challengePassword.len = strlen(challenge_password_buffer) - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usage("challenge password could not be read");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage("challenge password could not be read");
|
challengePassword.ptr = optarg;
|
||||||
|
challengePassword.len = strlen(optarg);
|
||||||
}
|
}
|
||||||
}
|
continue;
|
||||||
else
|
|
||||||
{
|
|
||||||
challengePassword.ptr = optarg;
|
|
||||||
challengePassword.len = strlen(optarg);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'u': /* -- url */
|
case 'u': /* -- url */
|
||||||
if (scep_url)
|
if (scep_url)
|
||||||
{
|
{
|
||||||
usage("only one URL argument allowed");
|
usage("only one URL argument allowed");
|
||||||
}
|
}
|
||||||
scep_url = optarg;
|
scep_url = optarg;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'm': /* --method */
|
case 'm': /* --method */
|
||||||
if (strcaseeq("get", optarg))
|
if (strcaseeq("get", optarg))
|
||||||
{
|
{
|
||||||
http_get_request = TRUE;
|
http_get_request = TRUE;
|
||||||
}
|
}
|
||||||
else if (strcaseeq("post", optarg))
|
else if (strcaseeq("post", optarg))
|
||||||
{
|
{
|
||||||
http_get_request = FALSE;
|
http_get_request = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage("invalid http request method specified");
|
usage("invalid http request method specified");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 't': /* --interval */
|
case 't': /* --interval */
|
||||||
poll_interval = atoi(optarg);
|
poll_interval = atoi(optarg);
|
||||||
if (poll_interval <= 0)
|
if (poll_interval <= 0)
|
||||||
{
|
{
|
||||||
usage("invalid interval specified");
|
usage("invalid interval specified");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'x': /* --maxpolltime */
|
case 'x': /* --maxpolltime */
|
||||||
max_poll_time = atoi(optarg);
|
max_poll_time = atoi(optarg);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'a': /*--algorithm */
|
case 'a': /*--algorithm */
|
||||||
{
|
{
|
||||||
const proposal_token_t *token;
|
const proposal_token_t *token;
|
||||||
|
|
||||||
token = proposal_get_token(optarg, strlen(optarg));
|
token = proposal_get_token(optarg, strlen(optarg));
|
||||||
if (token == NULL || token->type != ENCRYPTION_ALGORITHM)
|
if (token == NULL || token->type != ENCRYPTION_ALGORITHM)
|
||||||
{
|
{
|
||||||
usage("invalid algorithm specified");
|
usage("invalid algorithm specified");
|
||||||
|
}
|
||||||
|
pkcs7_symmetric_cipher = encryption_algorithm_to_oid(
|
||||||
|
token->algorithm, token->keysize);
|
||||||
|
if (pkcs7_symmetric_cipher == OID_UNKNOWN)
|
||||||
|
{
|
||||||
|
usage("unsupported encryption algorithm specified");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
pkcs7_symmetric_cipher = encryption_algorithm_to_oid(
|
|
||||||
token->algorithm, token->keysize);
|
|
||||||
if (pkcs7_symmetric_cipher == OID_UNKNOWN)
|
|
||||||
{
|
|
||||||
usage("unsupported encryption algorithm specified");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
case 'A': /* --debug-all */
|
case 'A': /* --debug-all */
|
||||||
base_debugging |= DBG_ALL;
|
base_debugging |= DBG_ALL;
|
||||||
continue;
|
continue;
|
||||||
case 'P': /* debug parsing */
|
case 'P': /* debug parsing */
|
||||||
base_debugging |= DBG_PARSING;
|
base_debugging |= DBG_PARSING;
|
||||||
continue;
|
continue;
|
||||||
case 'R': /* debug raw */
|
case 'R': /* debug raw */
|
||||||
base_debugging |= DBG_RAW;
|
base_debugging |= DBG_RAW;
|
||||||
continue;
|
continue;
|
||||||
case 'C': /* debug control */
|
case 'C': /* debug control */
|
||||||
base_debugging |= DBG_CONTROL;
|
base_debugging |= DBG_CONTROL;
|
||||||
continue;
|
continue;
|
||||||
case 'M': /* debug control more */
|
case 'M': /* debug control more */
|
||||||
base_debugging |= DBG_CONTROLMORE;
|
base_debugging |= DBG_CONTROLMORE;
|
||||||
continue;
|
continue;
|
||||||
case 'X': /* debug private */
|
case 'X': /* debug private */
|
||||||
base_debugging |= DBG_PRIVATE;
|
base_debugging |= DBG_PRIVATE;
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
usage("unknown option");
|
usage("unknown option");
|
||||||
}
|
}
|
||||||
/* break from loop */
|
/* break from loop */
|
||||||
break;
|
break;
|
||||||
@ -807,8 +805,8 @@ int main(int argc, char **argv)
|
|||||||
/* check for minimum key length */
|
/* check for minimum key length */
|
||||||
if (private_key->get_keysize(private_key) < RSA_MIN_OCTETS / BITS_PER_BYTE)
|
if (private_key->get_keysize(private_key) < RSA_MIN_OCTETS / BITS_PER_BYTE)
|
||||||
{
|
{
|
||||||
exit_scepclient("length of RSA key has to be at least %d bits"
|
exit_scepclient("length of RSA key has to be at least %d bits",
|
||||||
,RSA_MIN_OCTETS * BITS_PER_BYTE);
|
RSA_MIN_OCTETS * BITS_PER_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -853,13 +851,13 @@ int main(int argc, char **argv)
|
|||||||
DBG_log("building pkcs10 object:")
|
DBG_log("building pkcs10 object:")
|
||||||
)
|
)
|
||||||
pkcs10_req = lib->creds->create(lib->creds, CRED_CERTIFICATE,
|
pkcs10_req = lib->creds->create(lib->creds, CRED_CERTIFICATE,
|
||||||
CERT_PKCS10_REQUEST,
|
CERT_PKCS10_REQUEST,
|
||||||
BUILD_SIGNING_KEY, private_key,
|
BUILD_SIGNING_KEY, private_key,
|
||||||
BUILD_SUBJECT, subject,
|
BUILD_SUBJECT, subject,
|
||||||
BUILD_SUBJECT_ALTNAMES, subjectAltNames,
|
BUILD_SUBJECT_ALTNAMES, subjectAltNames,
|
||||||
BUILD_CHALLENGE_PWD, challengePassword,
|
BUILD_CHALLENGE_PWD, challengePassword,
|
||||||
BUILD_DIGEST_ALG, pkcs10_signature_alg,
|
BUILD_DIGEST_ALG, pkcs10_signature_alg,
|
||||||
BUILD_END);
|
BUILD_END);
|
||||||
if (!pkcs10_req)
|
if (!pkcs10_req)
|
||||||
{
|
{
|
||||||
exit_scepclient("generating pkcs10 request failed");
|
exit_scepclient("generating pkcs10 request failed");
|
||||||
@ -919,14 +917,14 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* generate a self-signed X.509 certificate */
|
/* generate a self-signed X.509 certificate */
|
||||||
x509_signer = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
x509_signer = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
BUILD_SIGNING_KEY, private_key,
|
BUILD_SIGNING_KEY, private_key,
|
||||||
BUILD_PUBLIC_KEY, public_key,
|
BUILD_PUBLIC_KEY, public_key,
|
||||||
BUILD_SUBJECT, subject,
|
BUILD_SUBJECT, subject,
|
||||||
BUILD_NOT_BEFORE_TIME, notBefore,
|
BUILD_NOT_BEFORE_TIME, notBefore,
|
||||||
BUILD_NOT_AFTER_TIME, notAfter,
|
BUILD_NOT_AFTER_TIME, notAfter,
|
||||||
BUILD_SERIAL, serialNumber,
|
BUILD_SERIAL, serialNumber,
|
||||||
BUILD_SUBJECT_ALTNAMES, subjectAltNames,
|
BUILD_SUBJECT_ALTNAMES, subjectAltNames,
|
||||||
BUILD_END);
|
BUILD_END);
|
||||||
if (!x509_signer)
|
if (!x509_signer)
|
||||||
{
|
{
|
||||||
exit_scepclient("generating certificate failed");
|
exit_scepclient("generating certificate failed");
|
||||||
@ -989,9 +987,9 @@ int main(int argc, char **argv)
|
|||||||
DBG_log("building pkcs7 request")
|
DBG_log("building pkcs7 request")
|
||||||
)
|
)
|
||||||
pkcs7 = scep_build_request(pkcs10_encoding,
|
pkcs7 = scep_build_request(pkcs10_encoding,
|
||||||
transID, SCEP_PKCSReq_MSG,
|
transID, SCEP_PKCSReq_MSG,
|
||||||
x509_ca_enc, pkcs7_symmetric_cipher,
|
x509_ca_enc, pkcs7_symmetric_cipher,
|
||||||
x509_signer, pkcs7_digest_alg, private_key);
|
x509_signer, pkcs7_digest_alg, private_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1002,8 +1000,9 @@ int main(int argc, char **argv)
|
|||||||
char *path = concatenate_paths(REQ_PATH, file_out_pkcs7);
|
char *path = concatenate_paths(REQ_PATH, file_out_pkcs7);
|
||||||
|
|
||||||
if (!chunk_write(pkcs7, path, "pkcs7 encrypted request", 0022, force))
|
if (!chunk_write(pkcs7, path, "pkcs7 encrypted request", 0022, force))
|
||||||
|
{
|
||||||
exit_scepclient("could not write pkcs7 file '%s'", path);
|
exit_scepclient("could not write pkcs7 file '%s'", path);
|
||||||
;
|
}
|
||||||
filetype_out &= ~PKCS7; /* delete PKCS7 flag */
|
filetype_out &= ~PKCS7; /* delete PKCS7 flag */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,12 +1036,12 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION,
|
if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION,
|
||||||
http_get_request, &scep_response))
|
http_get_request, &scep_response))
|
||||||
{
|
{
|
||||||
exit_scepclient("did not receive a valid scep response");
|
exit_scepclient("did not receive a valid scep response");
|
||||||
}
|
}
|
||||||
ugh = scep_parse_response(scep_response, transID, &data, &attrs
|
ugh = scep_parse_response(scep_response, transID, &data, &attrs,
|
||||||
, x509_ca_sig);
|
x509_ca_sig);
|
||||||
if (ugh != NULL)
|
if (ugh != NULL)
|
||||||
{
|
{
|
||||||
exit_scepclient(ugh);
|
exit_scepclient(ugh);
|
||||||
@ -1053,8 +1052,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
identification_t *issuer = x509_ca_sig->get_subject(x509_ca_sig);
|
identification_t *issuer = x509_ca_sig->get_subject(x509_ca_sig);
|
||||||
|
|
||||||
plog(" scep request pending, polling every %d seconds"
|
plog(" scep request pending, polling every %d seconds",
|
||||||
, poll_interval);
|
poll_interval);
|
||||||
poll_start = time_monotonic(NULL);
|
poll_start = time_monotonic(NULL);
|
||||||
issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc",
|
issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc",
|
||||||
issuer->get_encoding(issuer),
|
issuer->get_encoding(issuer),
|
||||||
@ -1062,8 +1061,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
while (attrs.pkiStatus == SCEP_PENDING)
|
while (attrs.pkiStatus == SCEP_PENDING)
|
||||||
{
|
{
|
||||||
if (max_poll_time > 0
|
if (max_poll_time > 0 &&
|
||||||
&& (time_monotonic(NULL) - poll_start >= max_poll_time))
|
(time_monotonic(NULL) - poll_start >= max_poll_time))
|
||||||
{
|
{
|
||||||
exit_scepclient("maximum poll time reached: %d seconds"
|
exit_scepclient("maximum poll time reached: %d seconds"
|
||||||
, max_poll_time);
|
, max_poll_time);
|
||||||
@ -1080,18 +1079,18 @@ int main(int argc, char **argv)
|
|||||||
)
|
)
|
||||||
|
|
||||||
chunk_free(&getCertInitial);
|
chunk_free(&getCertInitial);
|
||||||
getCertInitial = scep_build_request(issuerAndSubject
|
getCertInitial = scep_build_request(issuerAndSubject,
|
||||||
, transID, SCEP_GetCertInitial_MSG
|
transID, SCEP_GetCertInitial_MSG,
|
||||||
, x509_ca_enc, pkcs7_symmetric_cipher
|
x509_ca_enc, pkcs7_symmetric_cipher,
|
||||||
, x509_signer, pkcs7_digest_alg, private_key);
|
x509_signer, pkcs7_digest_alg, private_key);
|
||||||
|
|
||||||
if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION,
|
if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION,
|
||||||
http_get_request, &scep_response))
|
http_get_request, &scep_response))
|
||||||
{
|
{
|
||||||
exit_scepclient("did not receive a valid scep response");
|
exit_scepclient("did not receive a valid scep response");
|
||||||
}
|
}
|
||||||
ugh = scep_parse_response(scep_response, transID, &data, &attrs
|
ugh = scep_parse_response(scep_response, transID, &data, &attrs,
|
||||||
, x509_ca_sig);
|
x509_ca_sig);
|
||||||
if (ugh != NULL)
|
if (ugh != NULL)
|
||||||
{
|
{
|
||||||
exit_scepclient(ugh);
|
exit_scepclient(ugh);
|
||||||
@ -1105,13 +1104,13 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
envelopedData = data.content;
|
envelopedData = data.content;
|
||||||
|
|
||||||
if (data.type != OID_PKCS7_DATA
|
if (data.type != OID_PKCS7_DATA ||
|
||||||
|| !asn1_parse_simple_object(&envelopedData, ASN1_OCTET_STRING, 0, "data"))
|
!asn1_parse_simple_object(&envelopedData, ASN1_OCTET_STRING, 0, "data"))
|
||||||
{
|
{
|
||||||
exit_scepclient("contentInfo is not of type 'data'");
|
exit_scepclient("contentInfo is not of type 'data'");
|
||||||
}
|
}
|
||||||
if (!pkcs7_parse_envelopedData(envelopedData, &certData
|
if (!pkcs7_parse_envelopedData(envelopedData, &certData,
|
||||||
, serialNumber, private_key))
|
serialNumber, private_key))
|
||||||
{
|
{
|
||||||
exit_scepclient("could not decrypt envelopedData");
|
exit_scepclient("could not decrypt envelopedData");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user