summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cmp/build.info3
-rw-r--r--crypto/cmp/cmp_err.c13
-rw-r--r--crypto/cmp/cmp_hdr.c28
-rw-r--r--crypto/cmp/cmp_local.h64
-rw-r--r--crypto/cmp/cmp_msg.c131
-rw-r--r--crypto/cmp/cmp_server.c615
-rw-r--r--crypto/cmp/cmp_status.c98
-rw-r--r--crypto/cmp/cmp_util.c56
-rw-r--r--crypto/crmf/crmf_err.c12
-rw-r--r--crypto/crmf/crmf_lib.c68
-rw-r--r--crypto/err/openssl.txt11
11 files changed, 894 insertions, 205 deletions
diff --git a/crypto/cmp/build.info b/crypto/cmp/build.info
index 41a5899319..1667334e2a 100644
--- a/crypto/cmp/build.info
+++ b/crypto/cmp/build.info
@@ -1,3 +1,4 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
- cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c
+ cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
+ cmp_server.c
diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c
index f82ef9e325..0d311a8ddf 100644
--- a/crypto/cmp/cmp_err.c
+++ b/crypto/cmp/cmp_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -17,9 +17,12 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ALGORITHM_NOT_SUPPORTED),
"algorithm not supported"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTHASH_UNMATCHED), "certhash unmatched"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND),
"certificate not found"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTREQMSG_NOT_FOUND),
+ "certreqmsg not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTRESPONSE_NOT_FOUND),
"certresponse not found"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH),
@@ -48,10 +51,16 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RR), "error creating rr"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS),
"error parsing pkistatus"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROCESSING_MSG),
+ "error processing msg"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROTECTING_MESSAGE),
"error protecting message"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH),
"error setting certhash"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_TRANSFERRING_OUT),
+ "error transferring out"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_UNEXPECTED_CERTCONF),
+ "error unexpected certconf"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION),
"error validating protection"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
@@ -72,6 +81,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
"missing sender identification"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_STORE),
"missing trust store"},
+ {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED),
+ "multiple requests not supported"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES),
"multiple san sources"},
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"},
diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c
index 29f477f1b5..b5a9e9ba9e 100644
--- a/crypto/cmp/cmp_hdr.c
+++ b/crypto/cmp/cmp_hdr.c
@@ -153,25 +153,6 @@ int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
}
/* push the given text string to the given PKIFREETEXT ft */
-int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text)
-{
- ASN1_UTF8STRING *utf8string;
-
- if (!ossl_assert(ft != NULL && text != NULL))
- return 0;
- if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
- return 0;
- if (!ASN1_STRING_set(utf8string, text, -1))
- goto err;
- if (!sk_ASN1_UTF8STRING_push(ft, utf8string))
- goto err;
- return 1;
-
- err:
- ASN1_UTF8STRING_free(utf8string);
- return 0;
-}
-
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
{
if (!ossl_assert(hdr != NULL && text != NULL))
@@ -193,7 +174,8 @@ int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
&& (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL)
return 0;
- return ossl_cmp_pkifreetext_push_str(hdr->freeText, (char *)text->data);
+ return
+ ossl_cmp_sk_ASN1_UTF8STRING_push_str(hdr->freeText, (char *)text->data);
}
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
@@ -205,7 +187,7 @@ int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
}
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
- STACK_OF(OSSL_CMP_ITAV) *itavs)
+ const STACK_OF(OSSL_CMP_ITAV) *itavs)
{
int i;
OSSL_CMP_ITAV *itav;
@@ -250,7 +232,7 @@ int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr)
}
/* return 1 if implicitConfirm in the generalInfo field of the header is set */
-int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
+int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
{
int itavCount;
int i;
@@ -287,7 +269,7 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
X509_get_subject_name(ctx->clCert) : ctx->subjectName;
/*
* The sender name is copied from the subject of the client cert, if any,
- * or else from the the subject name provided for certification requests.
+ * or else from the subject name provided for certification requests.
* 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, which we take from any referenceValue given.
diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h
index 015a3d4e67..ebc42d8c52 100644
--- a/crypto/cmp/cmp_local.h
+++ b/crypto/cmp/cmp_local.h
@@ -246,7 +246,6 @@ struct ossl_cmp_itav_st {
} infoValue;
} /* OSSL_CMP_ITAV */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ITAV)
-DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV)
typedef struct ossl_cmp_certorenccert_st {
int type;
@@ -284,8 +283,6 @@ struct ossl_cmp_pkisi_st {
OSSL_CMP_PKIFREETEXT *statusString;
OSSL_CMP_PKIFAILUREINFO *failInfo;
} /* OSSL_CMP_PKISI */;
-DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
-DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI)
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
/*-
@@ -296,10 +293,11 @@ DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
* crlEntryDetails Extensions OPTIONAL
* }
*/
-typedef struct ossl_cmp_revdetails_st {
+struct ossl_cmp_revdetails_st {
OSSL_CRMF_CERTTEMPLATE *certDetails;
X509_EXTENSIONS *crlEntryDetails;
-} OSSL_CMP_REVDETAILS;
+} /* OSSL_CMP_REVDETAILS */;
+typedef struct ossl_cmp_revdetails_st OSSL_CMP_REVDETAILS;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVDETAILS)
DEFINE_STACK_OF(OSSL_CMP_REVDETAILS)
@@ -375,7 +373,6 @@ struct ossl_cmp_certstatus_st {
OSSL_CMP_PKISI *statusInfo;
} /* OSSL_CMP_CERTSTATUS */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS)
-
typedef STACK_OF(OSSL_CMP_CERTSTATUS) OSSL_CMP_CERTCONFIRMCONTENT;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTCONFIRMCONTENT)
@@ -670,7 +667,6 @@ struct ossl_cmp_msg_st {
STACK_OF(X509) *extraCerts; /* 1 */
} /* OSSL_CMP_MSG */;
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_MSG)
-DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG)
/*-
* ProtectedPart ::= SEQUENCE {
@@ -728,17 +724,6 @@ DECLARE_ASN1_FUNCTIONS(CMP_PROTECTEDPART)
* }
*/
-/*
- * constants
- */
-/* certReqId for the first - and so far only - certificate request */
-# define OSSL_CMP_CERTREQID 0
-/* sequence id for the first - and so far only - revocation request */
-# define OSSL_CMP_REVREQSID 0
-/*
- * functions
- */
-
/* from cmp_asn.c */
int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);
@@ -755,6 +740,9 @@ int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs,
int no_self_issued, int no_dups, int prepend);
int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
int only_self_issued);
+STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store);
+int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
+ const char *text);
int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
const ASN1_OCTET_STRING *src);
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
@@ -800,13 +788,11 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
const ASN1_OCTET_STRING *nonce);
/* from cmp_status.c */
-OSSL_CMP_PKISI *
-ossl_cmp_statusinfo_new(int status, int fail_info, const char *text);
-int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *statusInfo);
+int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
const char *ossl_cmp_PKIStatus_to_string(int status);
-OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si);
+OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
-int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index);
+int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
/* from cmp_hdr.c */
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
@@ -817,15 +803,14 @@ int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr);
int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
const ASN1_OCTET_STRING *senderKID);
-int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text);
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
OSSL_CMP_ITAV *itav);
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
- STACK_OF(OSSL_CMP_ITAV) *itavs);
+ const STACK_OF(OSSL_CMP_ITAV) *itavs);
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
-int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
+int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
# define OSSL_CMP_TRANSACTIONID_LENGTH 16
# define OSSL_CMP_SENDERNONCE_LENGTH 16
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
@@ -860,6 +845,10 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
# define OSSL_CMP_PKIBODY_POLLREQ 25
# define OSSL_CMP_PKIBODY_POLLREP 26
# define OSSL_CMP_PKIBODY_TYPE_MAX OSSL_CMP_PKIBODY_POLLREP
+/* certReqId for the first - and so far only - certificate request */
+# define OSSL_CMP_CERTREQID 0
+/* sequence id for the first - and so far only - revocation request */
+# define OSSL_CMP_REVREQSID 0
const char *ossl_cmp_bodytype_to_string(int type);
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type);
int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg);
@@ -875,24 +864,26 @@ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx);
OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
OSSL_CRMF_CERTID *certId, int unprot_err);
OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx);
+OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
+ int64_t poll_after);
int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav);
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
- STACK_OF(OSSL_CMP_ITAV) *itavs);
+ const STACK_OF(OSSL_CMP_ITAV) *itavs);
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx);
-OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx);
+OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
+ const STACK_OF(OSSL_CMP_ITAV) *itavs);
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
int errorCode,
- OSSL_CMP_PKIFREETEXT *errorDetails,
- int unprotected);
-int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
- const X509 *cert);
+ const char *details, int unprotected);
+int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
+ ASN1_OCTET_STRING *hash);
OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
const char *text);
OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid);
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
int64_t poll_after);
OSSL_CMP_PKISI *
-ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
+ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep,
int rsid);
OSSL_CMP_POLLREP *
@@ -904,11 +895,6 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crepmsg
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
const OSSL_CMP_CERTRESPONSE *crep);
OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
-/* BIO definitions */
-# define OSSL_d2i_CMP_MSG_bio(bp, p) \
- ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new, d2i_OSSL_CMP_MSG, bp, p)
-# define OSSL_i2d_CMP_MSG_bio(bp, o) \
- ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bp, o)
/* from cmp_protect.c */
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
@@ -925,4 +911,4 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
-#endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */
+#endif /* !defined(OSSL_CRYPTO_CMP_LOCAL_H) */
diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c
index c794dc98bb..c608568130 100644
--- a/crypto/cmp/cmp_msg.c
+++ b/crypto/cmp/cmp_msg.c
@@ -205,18 +205,20 @@ static X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
* Create CRMF certificate request message for IR/CR/KUR
* returns a pointer to the OSSL_CRMF_MSG on success, NULL on error
*/
-static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype,
- int rid, EVP_PKEY *rkey)
+static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, int rid)
{
OSSL_CRMF_MSG *crm = NULL;
X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->clCert;
/* refcert defaults to current client cert */
+ EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
STACK_OF(GENERAL_NAME) *default_sans = NULL;
X509_NAME *subject = determine_subj(ctx, refcert, bodytype);
int crit = ctx->setSubjectAltNameCritical || subject == NULL;
/* RFC5280: subjectAltName MUST be critical if subject is null */
X509_EXTENSIONS *exts = NULL;
+ if (rkey == NULL)
+ rkey = ctx->pkey; /* default is independent of ctx->oldClCert */
if (rkey == NULL
|| (bodytype == OSSL_CMP_PKIBODY_KUR && refcert == NULL)) {
CMPerr(0, CMP_R_INVALID_ARGS);
@@ -300,19 +302,12 @@ static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype,
OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
{
- EVP_PKEY *rkey;
- EVP_PKEY *privkey;
OSSL_CMP_MSG *msg;
OSSL_CRMF_MSG *crm = NULL;
if (!ossl_assert(ctx != NULL))
return NULL;
- rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
- if (rkey == NULL)
- return NULL;
- privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
-
if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR
&& type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) {
CMPerr(0, CMP_R_INVALID_ARGS);
@@ -329,15 +324,19 @@ OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
/* body */
/* For P10CR the content has already been set in OSSL_CMP_MSG_create */
if (type != OSSL_CMP_PKIBODY_P10CR) {
+ EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
+
+ if (privkey == NULL)
+ privkey = ctx->pkey; /* default is independent of ctx->oldCert */
if (ctx->popoMethod == OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) {
CMPerr(0, CMP_R_MISSING_PRIVATE_KEY);
goto err;
}
- if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID, rkey)) == NULL
- || !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest,
- ctx->popoMethod)
- /* value.ir is same for cr and kur */
- || !sk_OSSL_CRMF_MSG_push(msg->body->value.ir, crm))
+ if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID)) == NULL
+ || !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest,
+ ctx->popoMethod)
+ /* value.ir is same for cr and kur */
+ || !sk_OSSL_CRMF_MSG_push(msg->body->value.ir, crm))
goto err;
crm = NULL;
/* TODO: here optional 2nd certreqmsg could be pushed to the stack */
@@ -385,7 +384,7 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
|| !ASN1_INTEGER_set(resp->certReqId, certReqId))
goto err;
- status = ossl_cmp_pkisi_get_pkistatus(resp->status);
+ status = ossl_cmp_pkisi_get_status(resp->status);
if (status != OSSL_CMP_PKISTATUS_rejection
&& status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) {
if (encrypted) {
@@ -416,7 +415,7 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
goto err;
if (!unprotectedErrors
- || ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
+ || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
@@ -511,7 +510,7 @@ OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
}
if (!unprot_err
- || ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
+ || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
if (!ossl_cmp_msg_protect(ctx, msg))
goto err;
@@ -560,7 +559,7 @@ int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav)
}
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
- STACK_OF(OSSL_CMP_ITAV) *itavs)
+ const STACK_OF(OSSL_CMP_ITAV) *itavs)
{
int i;
OSSL_CMP_ITAV *itav = NULL;
@@ -583,7 +582,9 @@ int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
* Creates a new General Message/Response with an empty itav stack
* returns a pointer to the PKIMessage on success, NULL on error
*/
-static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
+static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx,
+ const STACK_OF(OSSL_CMP_ITAV) *itavs,
+ int body_type, int err_code)
{
OSSL_CMP_MSG *msg = NULL;
@@ -594,7 +595,7 @@ static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
return NULL;
if (ctx->genm_ITAVs != NULL
- && !ossl_cmp_msg_gen_push1_ITAVs(msg, ctx->genm_ITAVs))
+ && !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs))
goto err;
if (!ossl_cmp_msg_protect(ctx, msg))
@@ -610,20 +611,23 @@ static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
{
- return gen_new(ctx, OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
+ return gen_new(ctx, ctx->genm_ITAVs,
+ OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
}
-OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx)
+OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
+ const STACK_OF(OSSL_CMP_ITAV) *itavs)
{
- return gen_new(ctx, OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
+ return gen_new(ctx, itavs,
+ OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
}
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
int errorCode,
- OSSL_CMP_PKIFREETEXT *errorDetails,
- int unprotected)
+ const char *details, int unprotected)
{
OSSL_CMP_MSG *msg = NULL;
+ OSSL_CMP_PKIFREETEXT *ft;
if (!ossl_assert(ctx != NULL && si != NULL))
return NULL;
@@ -641,11 +645,13 @@ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
if (!ASN1_INTEGER_set(msg->body->value.error->errorCode, errorCode))
goto err;
}
- if (errorDetails != NULL)
- if ((msg->body->value.error->errorDetails =
- sk_ASN1_UTF8STRING_deep_copy(errorDetails, ASN1_STRING_dup,
- ASN1_STRING_free)) == NULL)
+ if (details != NULL) {
+ if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL)
+ goto err;
+ msg->body->value.error->errorDetails = ft;
+ if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details))
goto err;
+ }
if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
goto err;
@@ -658,44 +664,18 @@ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
}
/*
- * OSSL_CMP_CERTSTATUS_set_certHash() calculates a hash of the certificate,
- * using the same hash algorithm as is used to create and verify the
- * certificate signature, and places the hash into the certHash field of a
- * OSSL_CMP_CERTSTATUS structure. This is used in the certConf message,
- * for example, to confirm that the certificate was received successfully.
+ * Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
+ * This is used in the certConf message, for example,
+ * to confirm that the certificate was received successfully.
*/
-int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
- const X509 *cert)
+int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
+ ASN1_OCTET_STRING *hash)
{
- unsigned int len;
- unsigned char hash[EVP_MAX_MD_SIZE];
- int md_NID;
- const EVP_MD *md = NULL;
-
- if (!ossl_assert(certStatus != NULL && cert != NULL))
- return 0;
-
- /*-
- * select hash algorithm, as stated in Appendix F. Compilable ASN.1 defs:
- * the hash of the certificate, using the same hash algorithm
- * as is used to create and verify the certificate signature
- */
- if (OBJ_find_sigid_algs(X509_get_signature_nid(cert), &md_NID, NULL)
- && (md = EVP_get_digestbynid(md_NID)) != NULL) {
- if (!X509_digest(cert, md, hash, &len))
- goto err;
- if (!ossl_cmp_asn1_octet_string_set1_bytes(&certStatus->certHash, hash,
- len))
- goto err;
- } else {
- CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM);
+ if (!ossl_assert(certStatus != NULL))
return 0;
- }
-
+ ASN1_OCTET_STRING_free(certStatus->certHash);
+ certStatus->certHash = hash;
return 1;
- err:
- CMPerr(0, CMP_R_ERROR_SETTING_CERTHASH);
- return 0;
}
/*
@@ -707,6 +687,7 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
{
OSSL_CMP_MSG *msg = NULL;
OSSL_CMP_CERTSTATUS *certStatus = NULL;
+ ASN1_OCTET_STRING *certHash = NULL;
OSSL_CMP_PKISI *sinfo;
if (!ossl_assert(ctx != NULL && ctx->newCert != NULL))
@@ -732,8 +713,12 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
* the hash of the certificate, using the same hash algorithm
* as is used to create and verify the certificate signature
*/
- if (!ossl_cmp_certstatus_set_certHash(certStatus, ctx->newCert))
+ if ((certHash = OSSL_CMP_X509_digest(ctx->newCert)) == NULL)
+ goto err;
+
+ if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash))
goto err;
+ certHash = NULL;
/*
* For any particular CertStatus, omission of the statusInfo field
* indicates ACCEPTANCE of the specified certificate. Alternatively,
@@ -742,8 +727,8 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
* the CA/RA.
*/
sinfo = fail_info != 0 ?
- ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
- ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
+ OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
+ OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
if (sinfo == NULL)
goto err;
certStatus->statusInfo = sinfo;
@@ -756,6 +741,7 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
err:
CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF);
OSSL_CMP_MSG_free(msg);
+ ASN1_OCTET_STRING_free(certHash);
return NULL;
}
@@ -827,7 +813,7 @@ OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
* returns NULL on error
*/
OSSL_CMP_PKISI *
-ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
+ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
{
OSSL_CMP_PKISI *status;
@@ -994,3 +980,14 @@ OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file)
BIO_free(bio);
return msg;
}
+
+OSSL_CMP_MSG *OSSL_d2i_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg)
+{
+ return ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new,
+ d2i_OSSL_CMP_MSG, bio, msg);
+}
+
+int OSSL_i2d_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
+{
+ return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
+}
diff --git a/crypto/cmp/cmp_server.c b/crypto/cmp/cmp_server.c
new file mode 100644
index 0000000000..a91f67b264
--- /dev/null
+++ b/crypto/cmp/cmp_server.c
@@ -0,0 +1,615 @@
+/*
+ * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright Nokia 2007-2019
+ * Copyright Siemens AG 2015-2019
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* general CMP server functions */
+
+#include <openssl/asn1t.h>
+
+#include "cmp_local.h"
+
+/* explicit #includes not strictly needed since implied by the above: */
+#include <openssl/cmp.h>
+#include <openssl/err.h>
+
+/* the context for the generic CMP server */
+struct ossl_cmp_srv_ctx_st
+{
+ OSSL_CMP_CTX *ctx; /* Client CMP context, partly reused for srv */
+ void *custom_ctx; /* pointer to specific server context */
+
+ OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
+ OSSL_CMP_SRV_rr_cb_t process_rr;
+ OSSL_CMP_SRV_genm_cb_t process_genm;
+ OSSL_CMP_SRV_error_cb_t process_error;
+ OSSL_CMP_SRV_certConf_cb_t process_certConf;
+ OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
+
+ int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
+ int acceptUnprotected; /* Accept requests with no/invalid prot. */
+ int acceptRAVerified; /* Accept ir/cr/kur with POPO RAVerified */
+ int grantImplicitConfirm; /* Grant implicit confirmation if requested */
+
+}; /* OSSL_CMP_SRV_CTX */
+
+void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ if (srv_ctx == NULL)
+ return;
+
+ OSSL_CMP_CTX_free(srv_ctx->ctx);
+ OPENSSL_free(srv_ctx);
+}
+
+OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void)
+{
+ OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));
+
+ if (ctx == NULL)
+ goto err;
+
+ if ((ctx->ctx = OSSL_CMP_CTX_new()) == NULL)
+ goto err;
+
+ /* all other elements are initialized to 0 or NULL, respectively */
+ return ctx;
+ err:
+ OSSL_CMP_SRV_CTX_free(ctx);
+ return NULL;
+}
+
+int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
+ OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
+ OSSL_CMP_SRV_rr_cb_t process_rr,
+ OSSL_CMP_SRV_genm_cb_t process_genm,
+ OSSL_CMP_SRV_error_cb_t process_error,
+ OSSL_CMP_SRV_certConf_cb_t process_certConf,
+ OSSL_CMP_SRV_pollReq_cb_t process_pollReq)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->custom_ctx = custom_ctx;
+ srv_ctx->process_cert_request = process_cert_request;
+ srv_ctx->process_rr = process_rr;
+ srv_ctx->process_genm = process_genm;
+ srv_ctx->process_error = process_error;
+ srv_ctx->process_certConf = process_certConf;
+ srv_ctx->process_pollReq = process_pollReq;
+ return 1;
+}
+
+OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+ return srv_ctx->ctx;
+}
+
+void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return NULL;
+ }
+ return srv_ctx->custom_ctx;
+}
+
+int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->sendUnprotectedErrors = val != 0;
+ return 1;
+}
+
+int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->acceptUnprotected = val != 0;
+ return 1;
+}
+
+int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->acceptRAVerified = val != 0;
+ return 1;
+}
+
+int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
+ int val)
+{
+ if (srv_ctx == NULL) {
+ CMPerr(0, CMP_R_NULL_ARGUMENT);
+ return 0;
+ }
+ srv_ctx->grantImplicitConfirm = val != 0;
+ return 1;
+}
+
+/*
+ * Processes an ir/cr/p10cr/kur and returns a certification response.
+ * Only handles the first certification request contained in req
+ * returns an ip/cp/kup on success and NULL on error
+ */
+static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
+ const OSSL_CMP_MSG *req)
+{
+ OSSL_CMP_MSG *msg = NULL;
+ OSSL_CMP_PKISI *si = NULL;
+ X509 *certOut = NULL;
+ STACK_OF(X509) *chainOut = NULL, *caPubs = NULL;
+ const OSSL_CRMF_MSG *crm = NULL;
+ const X509_REQ *p10cr = NULL;
+ int bodytype;
+ int certReqId;
+
+ if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
+ return NULL;
+
+ switch (ossl_cmp_msg_get_bodytype(req)) {
+ case OSSL_CMP_PKIBODY_P10CR:
+ case OSSL_CMP_PKIBODY_CR:
+ bodytype = OSSL_CMP_PKIBODY_CP;
+ break;
+ case OSSL_CMP_PKIBODY_IR:
+ bodytype = OSSL_CMP_PKIBODY_IP;
+ break;
+ case OSSL_CMP_PKIBODY_KUR:
+ bodytype = OSSL_CMP_PKIBODY_KUP;
+ break;
+ default:
+ CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
+ return NULL;
+ }
+
+ if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) {
+ certReqId = OSSL_CMP_CERTREQID;
+ p10cr = req->body->value.p10cr;
+ } else {
+ OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */
+
+ if (sk_OSSL_CRMF_MSG_num(reqs) != 1) { /* TODO: handle case > 1 */
+ CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
+ return NULL;
+ }
+
+ if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
+ CMPerr(0, CMP_R_CERTREQMSG_NOT_FOUND);
+ return NULL;
+ }
+ certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
+ }
+
+ if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) {
+ /* Proof of possession could not be verified */
+ si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
+ 1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
+ ERR_reason_error_string(ERR_peek_error()));
+ if (si == NULL)
+ return NULL;
+ } else {
+ OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(req);
+
+ si = srv_ctx->process_cert_request(srv_ctx, req, certReqId, crm, p10cr,
+ &certOut, &chainOut, &caPubs);
+ if (si == NULL)
+ goto err;
+ /* set OSSL_CMP_OPT_IMPLICITCONFIRM if and only if transaction ends */
+ if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx, OSSL_CMP_OPT_IMPLICITCONFIRM,
+ ossl_cmp_hdr_has_implicitConfirm(hdr)
+ && srv_ctx->grantImplicitConfirm
+ /* do not set if polling starts: */
+ && certOut != NULL))
+ goto err;
+ }
+
+ msg = ossl_cmp_certRep_new(srv_ctx->ctx, bodytype, certReqId, si,
+ certOut, chainOut, caPubs, 0 /* encrypted */,
+ srv_ctx->sendUnprotectedErrors);
+ /*
+ * TODO when implemented in ossl_cmp_certrep_new():
+ * in case OSSL_CRMF_POPO_KEYENC, set encrypted
+ */
+ if (msg == NULL)
+ CMPerr(0, CMP_R_ERROR_CREATING_CERTREP);
+
+ err:
+