summaryrefslogtreecommitdiffstats
path: root/crypto/cmp/cmp_protect.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/cmp/cmp_protect.c')
-rw-r--r--crypto/cmp/cmp_protect.c130
1 files changed, 61 insertions, 69 deletions
diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c
index 3e0c22bb80..0b87acd804 100644
--- a/crypto/cmp/cmp_protect.c
+++ b/crypto/cmp/cmp_protect.c
@@ -145,21 +145,18 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
&& (msg->extraCerts = sk_X509_new_null()) == NULL)
return 0;
- if (ctx->clCert != NULL) {
- /* Make sure that our own cert gets sent, in the first position */
- if (!X509_up_ref(ctx->clCert))
+ if (ctx->clCert != NULL && ctx->pkey != NULL) {
+ /* make sure that our own cert is included in the first position */
+ if (!ossl_cmp_sk_X509_add1_cert(msg->extraCerts, ctx->clCert, 1, 1))
return 0;
- if (!sk_X509_push(msg->extraCerts, ctx->clCert)) {
- X509_free(ctx->clCert);
- return 0;
- }
- /* if we have untrusted store, try to add intermediate certs */
+ /* if we have untrusted certs, try to add intermediate certs */
if (ctx->untrusted_certs != NULL) {
STACK_OF(X509) *chain =
ossl_cmp_build_cert_chain(ctx->untrusted_certs, ctx->clCert);
int res = ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain,
1 /* no self-issued */,
1 /* no duplicates */, 0);
+
sk_X509_pop_free(chain, X509_free);
if (res == 0)
return 0;
@@ -227,6 +224,15 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
if (!ossl_assert(ctx != NULL && msg != NULL))
return 0;
+ /*
+ * For the case of re-protection remove pre-existing protection.
+ * TODO: Consider also removing any pre-existing extraCerts.
+ */
+ X509_ALGOR_free(msg->header->protectionAlg);
+ msg->header->protectionAlg = NULL;
+ ASN1_BIT_STRING_free(msg->protection);
+ msg->protection = NULL;
+
if (ctx->unprotectedSend)
return 1;
@@ -238,84 +244,70 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
&& !ossl_cmp_hdr_set1_senderKID(msg->header,
ctx->referenceValue))
goto err;
-
- /*
- * add any additional certificates from ctx->extraCertsOut
- * while not needed to validate the signing cert, the option to do
- * this might be handy for certain use cases
- */
- if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
- goto err;
-
- if ((msg->protection =
- ossl_cmp_calc_protection(msg, ctx->secretValue, NULL)) == NULL)
- goto err;
- } else {
+ } else if (ctx->clCert != NULL && ctx->pkey != NULL) {
/*
* use MSG_SIG_ALG according to 5.1.3.3 if client Certificate and
* private key is given
*/
- if (ctx->clCert != NULL && ctx->pkey != NULL) {
- const ASN1_OCTET_STRING *subjKeyIDStr = NULL;
- int algNID = 0;
- ASN1_OBJECT *alg = NULL;
-
- /* make sure that key and certificate match */
- if (!X509_check_private_key(ctx->clCert, ctx->pkey)) {
- CMPerr(0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH);
- goto err;
- }
-
- if (msg->header->protectionAlg == NULL)
- if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
- goto err;
+ const ASN1_OCTET_STRING *subjKeyIDStr = NULL;
+ int algNID = 0;
+ ASN1_OBJECT *alg = NULL;
- if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
- EVP_PKEY_id(ctx->pkey))) {
- CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
- goto err;
- }
- if ((alg = OBJ_nid2obj(algNID)) == NULL)
- goto err;
- if (!X509_ALGOR_set0(msg->header->protectionAlg,
- alg, V_ASN1_UNDEF, NULL)) {
- ASN1_OBJECT_free(alg);
- goto err;
- }
-
- /*
- * set senderKID to keyIdentifier of the used certificate according
- * to section 5.1.1
- */
- subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert);
- if (subjKeyIDStr == NULL)
- subjKeyIDStr = ctx->referenceValue; /* fallback */
- if (subjKeyIDStr != NULL
- && !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
- goto err;
+ /* make sure that key and certificate match */
+ if (!X509_check_private_key(ctx->clCert, ctx->pkey)) {
+ CMPerr(0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH);
+ goto err;
+ }
- /*
- * Add ctx->clCert followed, if possible, by its chain built
- * from ctx->untrusted_certs, and then ctx->extraCertsOut
- */
- if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
+ if (msg->header->protectionAlg == NULL)
+ if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
goto err;
- if ((msg->protection =
- ossl_cmp_calc_protection(msg, NULL, ctx->pkey)) == NULL)
- goto err;
- } else {
- CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
+ if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
+ EVP_PKEY_id(ctx->pkey))) {
+ CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
goto err;
}
+ if ((alg = OBJ_nid2obj(algNID)) == NULL)
+ goto err;
+ if (!X509_ALGOR_set0(msg->header->protectionAlg, alg,
+ V_ASN1_UNDEF, NULL)) {
+ ASN1_OBJECT_free(alg);
+ goto err;
+ }
+
+ /*
+ * set senderKID to keyIdentifier of the used certificate according
+ * to section 5.1.1
+ */
+ subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert);
+ if (subjKeyIDStr == NULL)
+ subjKeyIDStr = ctx->referenceValue; /* fallback */
+ if (subjKeyIDStr != NULL
+ && !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
+ goto err;
+ } else {
+ CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
+ goto err;
}
+ if ((msg->protection =
+ ossl_cmp_calc_protection(msg, ctx->secretValue, ctx->pkey)) == NULL)
+ goto err;
+
+ /*
+ * If present, add ctx->clCert followed by its chain as far as possible.
+ * Finally add any additional certificates from ctx->extraCertsOut;
+ * even if not needed to validate the protection
+ * the option to do this might be handy for certain use cases.
+ */
+ if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
+ goto err;
/*
* As required by RFC 4210 section 5.1.1., if the sender name is not known
* to the client it set to NULL-DN. In this case for identification at least
* the senderKID must be set, where we took the referenceValue as fallback.
*/
-
if (ossl_cmp_general_name_is_NULL_DN(msg->header->sender)
&& msg->header->senderKID == NULL)
CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION);