diff options
-rwxr-xr-x | Configure | 1 | ||||
-rw-r--r-- | crypto/build.info | 2 | ||||
-rw-r--r-- | crypto/crmf/build.info | 2 | ||||
-rw-r--r-- | crypto/crmf/crmf_asn.c | 240 | ||||
-rw-r--r-- | crypto/crmf/crmf_err.c | 104 | ||||
-rw-r--r-- | crypto/crmf/crmf_int.h | 394 | ||||
-rw-r--r-- | crypto/crmf/crmf_lib.c | 753 | ||||
-rw-r--r-- | crypto/crmf/crmf_pbm.c | 231 | ||||
-rw-r--r-- | crypto/err/err.c | 1 | ||||
-rw-r--r-- | crypto/err/err_all.c | 4 | ||||
-rw-r--r-- | crypto/err/openssl.ec | 1 | ||||
-rw-r--r-- | crypto/err/openssl.txt | 41 | ||||
-rw-r--r-- | doc/man3/OSSL_CRMF_MSG_set1_regCtrl_regToken.pod | 9 | ||||
-rw-r--r-- | doc/man3/OSSL_CRMF_MSG_set_validity.pod | 12 | ||||
-rw-r--r-- | doc/man3/OSSL_CRMF_pbmp_new.pod | 22 | ||||
-rw-r--r-- | include/openssl/crmf.h | 16 | ||||
-rw-r--r-- | include/openssl/crmferr.h | 69 | ||||
-rw-r--r-- | include/openssl/err.h | 2 | ||||
-rw-r--r-- | util/libcrypto.num | 82 |
19 files changed, 1957 insertions, 29 deletions
@@ -349,6 +349,7 @@ my @disablables = ( "cmac", "cms", "comp", + "crmf", "crypto-mdebug", "crypto-mdebug-backtrace", "ct", diff --git a/crypto/build.info b/crypto/build.info index 0cca6ab7a3..a1ccad44ea 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \ md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ - err comp ocsp cms ts srp cmac ct async kmac ess + err comp ocsp cms ts srp cmac ct async kmac ess crmf LIBS=../libcrypto # The Core diff --git a/crypto/crmf/build.info b/crypto/crmf/build.info new file mode 100644 index 0000000000..7cfa8ec2b0 --- /dev/null +++ b/crypto/crmf/build.info @@ -0,0 +1,2 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=crmf_asn.c crmf_err.c crmf_lib.c crmf_pbm.c diff --git a/crypto/crmf/crmf_asn.c b/crypto/crmf/crmf_asn.c new file mode 100644 index 0000000000..d0ab6e95bc --- /dev/null +++ b/crypto/crmf/crmf_asn.c @@ -0,0 +1,240 @@ +/*- + * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2018 + * Copyright Siemens AG 2015-2018 + * + * Licensed under the OpenSSL license (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 + * + * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. + */ + +#include <openssl/asn1t.h> + +#include "crmf_int.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include <openssl/crmf.h> + +ASN1_SEQUENCE(OSSL_CRMF_PRIVATEKEYINFO) = { + ASN1_SIMPLE(OSSL_CRMF_PRIVATEKEYINFO, version, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_PRIVATEKEYINFO, privateKeyAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_PRIVATEKEYINFO, privateKey, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(OSSL_CRMF_PRIVATEKEYINFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END(OSSL_CRMF_PRIVATEKEYINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PRIVATEKEYINFO) + + +ASN1_CHOICE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) = { + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, value.string, ASN1_UTF8STRING), + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER, value.generalName, GENERAL_NAME) +} ASN1_CHOICE_END(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) + + +ASN1_SEQUENCE(OSSL_CRMF_ENCKEYWITHID) = { + ASN1_SIMPLE(OSSL_CRMF_ENCKEYWITHID, privateKey, OSSL_CRMF_PRIVATEKEYINFO), + ASN1_OPT(OSSL_CRMF_ENCKEYWITHID, identifier, + OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) +} ASN1_SEQUENCE_END(OSSL_CRMF_ENCKEYWITHID) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID) + + +ASN1_SEQUENCE(OSSL_CRMF_CERTID) = { + ASN1_SIMPLE(OSSL_CRMF_CERTID, issuer, GENERAL_NAME), + ASN1_SIMPLE(OSSL_CRMF_CERTID, serialNumber, ASN1_INTEGER) +} ASN1_SEQUENCE_END(OSSL_CRMF_CERTID) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTID) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) + + +ASN1_SEQUENCE(OSSL_CRMF_ENCRYPTEDVALUE) = { + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, intendedAlg, X509_ALGOR, 0), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, symmAlg, X509_ALGOR, 1), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, encSymmKey, ASN1_BIT_STRING, 2), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, keyAlg, X509_ALGOR, 3), + ASN1_IMP_OPT(OSSL_CRMF_ENCRYPTEDVALUE, valueHint, ASN1_OCTET_STRING, 4), + ASN1_SIMPLE(OSSL_CRMF_ENCRYPTEDVALUE, encValue, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(OSSL_CRMF_ENCRYPTEDVALUE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE) + +ASN1_SEQUENCE(OSSL_CRMF_SINGLEPUBINFO) = { + ASN1_SIMPLE(OSSL_CRMF_SINGLEPUBINFO, pubMethod, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_SINGLEPUBINFO, pubLocation, GENERAL_NAME) +} ASN1_SEQUENCE_END(OSSL_CRMF_SINGLEPUBINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_SINGLEPUBINFO) + + +ASN1_SEQUENCE(OSSL_CRMF_PKIPUBLICATIONINFO) = { + ASN1_SIMPLE(OSSL_CRMF_PKIPUBLICATIONINFO, action, ASN1_INTEGER), + ASN1_SEQUENCE_OF_OPT(OSSL_CRMF_PKIPUBLICATIONINFO, pubInfos, + OSSL_CRMF_SINGLEPUBINFO) +} ASN1_SEQUENCE_END(OSSL_CRMF_PKIPUBLICATIONINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PKIPUBLICATIONINFO) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_PKIPUBLICATIONINFO) + + +ASN1_SEQUENCE(OSSL_CRMF_PKMACVALUE) = { + ASN1_SIMPLE(OSSL_CRMF_PKMACVALUE, algId, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_PKMACVALUE, value, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(OSSL_CRMF_PKMACVALUE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PKMACVALUE) + + +ASN1_CHOICE(OSSL_CRMF_POPOPRIVKEY) = { + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.thisMessage, ASN1_BIT_STRING, 0), + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.subsequentMessage, ASN1_INTEGER, 1), + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.dhMAC, ASN1_BIT_STRING, 2), + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.agreeMAC, OSSL_CRMF_PKMACVALUE, 3), + /* + * TODO: This is not ASN1_NULL but CMS_ENVELOPEDDATA which should be somehow + * taken from crypto/cms which exists now - this is not used anywhere so far + */ + ASN1_IMP(OSSL_CRMF_POPOPRIVKEY, value.encryptedKey, ASN1_NULL, 4), +} ASN1_CHOICE_END(OSSL_CRMF_POPOPRIVKEY) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOPRIVKEY) + + +ASN1_SEQUENCE(OSSL_CRMF_PBMPARAMETER) = { + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, salt, ASN1_OCTET_STRING), + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, owf, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, iterationCount, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_PBMPARAMETER, mac, X509_ALGOR) +} ASN1_SEQUENCE_END(OSSL_CRMF_PBMPARAMETER) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_PBMPARAMETER) + + +ASN1_CHOICE(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) = { + ASN1_EXP(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO, value.sender, + GENERAL_NAME, 0), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO, value.publicKeyMAC, + OSSL_CRMF_PKMACVALUE) +} ASN1_CHOICE_END(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) + + +ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEYINPUT) = { + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEYINPUT, authInfo, + OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEYINPUT, publicKey, X509_PUBKEY) +} ASN1_SEQUENCE_END(OSSL_CRMF_POPOSIGNINGKEYINPUT) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT) + + +ASN1_SEQUENCE(OSSL_CRMF_POPOSIGNINGKEY) = { + ASN1_IMP_OPT(OSSL_CRMF_POPOSIGNINGKEY, poposkInput, + OSSL_CRMF_POPOSIGNINGKEYINPUT, 0), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEY, algorithmIdentifier, X509_ALGOR), + ASN1_SIMPLE(OSSL_CRMF_POPOSIGNINGKEY, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(OSSL_CRMF_POPOSIGNINGKEY) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEY) + + +ASN1_CHOICE(OSSL_CRMF_POPO) = { + ASN1_IMP(OSSL_CRMF_POPO, value.raVerified, ASN1_NULL, 0), + ASN1_IMP(OSSL_CRMF_POPO, value.signature, OSSL_CRMF_POPOSIGNINGKEY, 1), + ASN1_EXP(OSSL_CRMF_POPO, value.keyEncipherment, OSSL_CRMF_POPOPRIVKEY, 2), + ASN1_EXP(OSSL_CRMF_POPO, value.keyAgreement, OSSL_CRMF_POPOPRIVKEY, 3) +} ASN1_CHOICE_END(OSSL_CRMF_POPO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_POPO) + + +ASN1_ADB_TEMPLATE(attributetypeandvalue_default) = ASN1_OPT( + OSSL_CRMF_ATTRIBUTETYPEANDVALUE, value.other, ASN1_ANY); +ASN1_ADB(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { + ADB_ENTRY(NID_id_regCtrl_regToken, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.regToken, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_regCtrl_authenticator, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.authenticator, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_regCtrl_pkiPublicationInfo, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.pkiPublicationInfo, + OSSL_CRMF_PKIPUBLICATIONINFO)), + ADB_ENTRY(NID_id_regCtrl_oldCertID, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.oldCertID, OSSL_CRMF_CERTID)), + ADB_ENTRY(NID_id_regCtrl_protocolEncrKey, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.protocolEncrKey, X509_PUBKEY)), + ADB_ENTRY(NID_id_regInfo_utf8Pairs, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.utf8Pairs, ASN1_UTF8STRING)), + ADB_ENTRY(NID_id_regInfo_certReq, + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, + value.certReq, OSSL_CRMF_CERTREQUEST)), +} ASN1_ADB_END(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, 0, type, 0, + &attributetypeandvalue_default_tt, NULL); + + +ASN1_SEQUENCE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) = { + ASN1_SIMPLE(OSSL_CRMF_ATTRIBUTETYPEANDVALUE, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +} ASN1_SEQUENCE_END(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) + +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) + + +ASN1_SEQUENCE(OSSL_CRMF_OPTIONALVALIDITY) = { + ASN1_EXP_OPT(OSSL_CRMF_OPTIONALVALIDITY, notBefore, ASN1_TIME, 0), + ASN1_EXP_OPT(OSSL_CRMF_OPTIONALVALIDITY, notAfter, ASN1_TIME, 1) +} ASN1_SEQUENCE_END(OSSL_CRMF_OPTIONALVALIDITY) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_OPTIONALVALIDITY) + + +ASN1_SEQUENCE(OSSL_CRMF_CERTTEMPLATE) = { + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, version, ASN1_INTEGER, 0), + /* + * serialNumber MUST be omitted. This field is assigned by the CA + * during certificate creation. + */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, serialNumber, ASN1_INTEGER, 1), + /* + * signingAlg MUST be omitted. This field is assigned by the CA + * during certificate creation. + */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, signingAlg, X509_ALGOR, 2), + ASN1_EXP_OPT(OSSL_CRMF_CERTTEMPLATE, issuer, X509_NAME, 3), + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, validity, + OSSL_CRMF_OPTIONALVALIDITY, 4), + ASN1_EXP_OPT(OSSL_CRMF_CERTTEMPLATE, subject, X509_NAME, 5), + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, publicKey, X509_PUBKEY, 6), + /* issuerUID is deprecated in version 2 */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, issuerUID, ASN1_BIT_STRING, 7), + /* subjectUID is deprecated in version 2 */ + ASN1_IMP_OPT(OSSL_CRMF_CERTTEMPLATE, subjectUID, ASN1_BIT_STRING, 8), + ASN1_IMP_SEQUENCE_OF_OPT(OSSL_CRMF_CERTTEMPLATE, extensions, + X509_EXTENSION, 9), +} ASN1_SEQUENCE_END(OSSL_CRMF_CERTTEMPLATE) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTTEMPLATE) + + +ASN1_SEQUENCE(OSSL_CRMF_CERTREQUEST) = { + ASN1_SIMPLE(OSSL_CRMF_CERTREQUEST, certReqId, ASN1_INTEGER), + ASN1_SIMPLE(OSSL_CRMF_CERTREQUEST, certTemplate, OSSL_CRMF_CERTTEMPLATE), + ASN1_SEQUENCE_OF_OPT(OSSL_CRMF_CERTREQUEST, controls, + OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +} ASN1_SEQUENCE_END(OSSL_CRMF_CERTREQUEST) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST) +IMPLEMENT_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST) + + +ASN1_SEQUENCE(OSSL_CRMF_MSG) = { + ASN1_SIMPLE(OSSL_CRMF_MSG, certReq, OSSL_CRMF_CERTREQUEST), + ASN1_OPT(OSSL_CRMF_MSG, popo, OSSL_CRMF_POPO), + ASN1_SEQUENCE_OF_OPT(OSSL_CRMF_MSG, regInfo, + OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +} ASN1_SEQUENCE_END(OSSL_CRMF_MSG) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSG) + + +ASN1_ITEM_TEMPLATE(OSSL_CRMF_MSGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + OSSL_CRMF_MSGS, OSSL_CRMF_MSG) + ASN1_ITEM_TEMPLATE_END(OSSL_CRMF_MSGS) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_CRMF_MSGS) + diff --git a/crypto/crmf/crmf_err.c b/crypto/crmf/crmf_err.c new file mode 100644 index 0000000000..f3405b112f --- /dev/null +++ b/crypto/crmf/crmf_err.c @@ -0,0 +1,104 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 + */ + +#include <openssl/err.h> +#include <openssl/crmferr.h> + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA CRMF_str_functs[] = { + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_CRMF_POPOSIGNINGKEY_INIT, 0), + "CRMF_poposigningkey_init"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_CERTID_GEN, 0), + "OSSL_CRMF_CERTID_gen"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL, 0), + "OSSL_CRMF_CERTTEMPLATE_fill"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, 0), + "OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, 0), + "OSSL_CRMF_MSGS_verify_popo"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, 0), + "OSSL_CRMF_MSG_create_popo"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_GET0_TMPL, 0), + "OSSL_CRMF_MSG_get0_tmpl"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, 0), + "OSSL_CRMF_MSG_get_certReqId"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PKIPUBLICATIONINFO_PUSH0_SINGLEPUBINFO, 0), + "OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PUSH0_EXTENSION, 0), + "OSSL_CRMF_MSG_push0_extension"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PUSH0_REGCTRL, 0), + "OSSL_CRMF_MSG_push0_regCtrl"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_PUSH0_REGINFO, 0), + "OSSL_CRMF_MSG_push0_regInfo"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET0_EXTENSIONS, 0), + "OSSL_CRMF_MSG_set0_extensions"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET0_SINGLEPUBINFO, 0), + "OSSL_CRMF_MSG_set0_SinglePubInfo"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET_CERTREQID, 0), + "OSSL_CRMF_MSG_set_certReqId"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET_PKIPUBLICATIONINFO_ACTION, 0), + "OSSL_CRMF_MSG_set_PKIPublicationInfo_action"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_MSG_SET_VALIDITY, 0), + "OSSL_CRMF_MSG_set_validity"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_PBMP_NEW, 0), + "OSSL_CRMF_pbmp_new"}, + {ERR_PACK(ERR_LIB_CRMF, CRMF_F_OSSL_CRMF_PBM_NEW, 0), "OSSL_CRMF_pbm_new"}, + {0, NULL} +}; + +static const ERR_STRING_DATA CRMF_str_reasons[] = { + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_BAD_PBM_ITERATIONCOUNT), + "bad pbm iterationcount"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CRMFERROR), "crmferror"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR), "error"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_CERTIFICATE), + "error decoding certificate"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_CERTIFICATE), + "error decrypting certificate"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY), + "error decrypting symmetric key"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_FAILURE_OBTAINING_RANDOM), + "failure obtaining random"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ITERATIONCOUNT_BELOW_100), + "iterationcount below 100"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE), + "setting mac algor failure"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE), + "setting owf algor failure"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM), + "unsupported algorithm"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY), + "unsupported alg for popsigningkey"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER), + "unsupported cipher"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO), + "unsupported method for creating popo"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD), + "unsupported popo method"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED), + "unsupported popo not accepted"}, + {0, NULL} +}; + +#endif + +int ERR_load_CRMF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(CRMF_str_functs[0].error) == NULL) { + ERR_load_strings_const(CRMF_str_functs); + ERR_load_strings_const(CRMF_str_reasons); + } +#endif + return 1; +} diff --git a/crypto/crmf/crmf_int.h b/crypto/crmf/crmf_int.h new file mode 100644 index 0000000000..db1547b0ef --- /dev/null +++ b/crypto/crmf/crmf_int.h @@ -0,0 +1,394 @@ +/*- + * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2018 + * Copyright Siemens AG 2015-2018 + * + * Licensed under the OpenSSL license (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 + * + * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. + */ + +#ifndef OSSL_HEADER_CRMF_INT_H +# define OSSL_HEADER_CRMF_INT_H + +# include <openssl/crmf.h> +# include <openssl/err.h> + +/* explicit #includes not strictly needed since implied by the above: */ +# include <openssl/ossl_typ.h> +# include <openssl/safestack.h> +# include <openssl/x509.h> +# include <openssl/x509v3.h> + +/*- + * EncryptedValue ::= SEQUENCE { + * intendedAlg [0] AlgorithmIdentifier OPTIONAL, + * -- the intended algorithm for which the value will be used + * symmAlg [1] AlgorithmIdentifier OPTIONAL, + * -- the symmetric algorithm used to encrypt the value + * encSymmKey [2] BIT STRING OPTIONAL, + * -- the (encrypted) symmetric key used to encrypt the value + * keyAlg [3] AlgorithmIdentifier OPTIONAL, + * -- algorithm used to encrypt the symmetric key + * valueHint [4] OCTET STRING OPTIONAL, + * -- a brief description or identifier of the encValue content + * -- (may be meaningful only to the sending entity, and + * -- used only if EncryptedValue might be re-examined + * -- by the sending entity in the future) + * encValue BIT STRING + * -- the encrypted value itself + * } + */ +struct OSSL_crmf_encryptedvalue_st { + X509_ALGOR *intendedAlg; /* 0 */ + X509_ALGOR *symmAlg; /* 1 */ + ASN1_BIT_STRING *encSymmKey; /* 2 */ + X509_ALGOR *keyAlg; /* 3 */ + ASN1_OCTET_STRING *valueHint; /* 4 */ + ASN1_BIT_STRING *encValue; +} /* OSSL_CRMF_ENCRYPTEDVALUE */; + +/*- + * Attributes ::= SET OF Attribute + * => X509_ATTRIBUTE + * + * PrivateKeyInfo ::= SEQUENCE { + * version INTEGER, + * privateKeyAlgorithm AlgorithmIdentifier, + * privateKey OCTET STRING, + * attributes [0] IMPLICIT Attributes OPTIONAL + * } + */ +typedef struct OSSL_crmf_privatekeyinfo_st { + ASN1_INTEGER *version; + X509_ALGOR *privateKeyAlgorithm; + ASN1_OCTET_STRING *privateKey; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} OSSL_CRMF_PRIVATEKEYINFO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PRIVATEKEYINFO) + +/*- + * section 4.2.1 Private Key Info Content Type + * id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} + * + * EncKeyWithID ::= SEQUENCE { + * privateKey PrivateKeyInfo, + * identifier CHOICE { + * string UTF8String, + * generalName GeneralName + * } OPTIONAL + * } + */ +typedef struct OSSL_crmf_enckeywithid_identifier_st { + int type; + union { + ASN1_UTF8STRING *string; + GENERAL_NAME *generalName; + } value; +} OSSL_CRMF_ENCKEYWITHID_IDENTIFIER; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) + +typedef struct OSSL_crmf_enckeywithid_st { + OSSL_CRMF_PRIVATEKEYINFO *privateKey; + /* [0] */ + OSSL_CRMF_ENCKEYWITHID_IDENTIFIER *identifier; +} OSSL_CRMF_ENCKEYWITHID; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID) + +/*- + * CertId ::= SEQUENCE { + * issuer GeneralName, + * serialNumber INTEGER + * } + */ +struct OSSL_crmf_certid_st { + GENERAL_NAME *issuer; + ASN1_INTEGER *serialNumber; +} /* OSSL_CRMF_CERTID */; +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) + +/*- + * SinglePubInfo ::= SEQUENCE { + * pubMethod INTEGER { + * dontCare (0), + * x500 (1), + * web (2), + * ldap (3) }, + * pubLocation GeneralName OPTIONAL + * } + */ +struct OSSL_crmf_singlepubinfo_st { + ASN1_INTEGER *pubMethod; + GENERAL_NAME *pubLocation; +} /* OSSL_CRMF_SINGLEPUBINFO */; +DEFINE_STACK_OF(OSSL_CRMF_SINGLEPUBINFO) +typedef STACK_OF(OSSL_CRMF_SINGLEPUBINFO) OSSL_CRMF_PUBINFOS; + + +/*- + * PKIPublicationInfo ::= SEQUENCE { + * action INTEGER { + * dontPublish (0), + * pleasePublish (1) }, + * pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL + * -- pubInfos MUST NOT be present if action is "dontPublish" + * -- (if action is "pleasePublish" and pubInfos is omitted, + * -- "dontCare" is assumed) + * } + */ +struct OSSL_crmf_pkipublicationinfo_st { + ASN1_INTEGER *action; + OSSL_CRMF_PUBINFOS *pubInfos; +} /* OSSL_CRMF_PKIPUBLICATIONINFO */; +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_PKIPUBLICATIONINFO) + +/*- + * PKMACValue ::= SEQUENCE { + * algId AlgorithmIdentifier, + * -- algorithm value shall be PasswordBasedMac {1 2 840 113533 7 66 13} + * -- parameter value is PBMParameter + * value BIT STRING + * } + */ +typedef struct OSSL_crmf_pkmacvalue_st { + X509_ALGOR *algId; + ASN1_BIT_STRING *value; +} OSSL_CRMF_PKMACVALUE; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PKMACVALUE) + +/*- + * SubsequentMessage ::= INTEGER { + * encrCert (0), + * -- requests that resulting certificate be encrypted for the + * -- end entity (following which, POP will be proven in a + * -- confirmation message) + * challengeResp (1) + * -- requests that CA engage in challenge-response exchange with + * -- end entity in order to prove private key possession + * } + * + * POPOPrivKey ::= CHOICE { + * thisMessage [0] BIT STRING, -- Deprecated + * -- possession is proven in this message (which contains the private + * -- key itself (encrypted for the CA)) + * subsequentMessage [1] SubsequentMessage, + * -- possession will be proven in a subsequent message + * dhMAC [2] BIT STRING, -- Deprecated + * agreeMAC [3] PKMACValue, + * encryptedKey [4] EnvelopedData + * } + */ + +typedef struct OSSL_crmf_popoprivkey_st { + int type; + union { + ASN1_BIT_STRING *thisMessage; /* 0 */ /* Deprecated */ + ASN1_INTEGER *subsequentMessage; /* 1 */ + ASN1_BIT_STRING *dhMAC; /* 2 */ /* Deprecated */ + OSSL_CRMF_PKMACVALUE *agreeMAC; /* 3 */ + /* + * TODO: This is not ASN1_NULL but CMS_ENVELOPEDDATA which should be + * somehow taken from crypto/cms which exists now + * - this is not used anywhere so far + */ + ASN1_NULL *encryptedKey; /* 4 */ + } value; +} OSSL_CRMF_POPOPRIVKEY; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOPRIVKEY) + +/*- + * PBMParameter ::= SEQUENCE { + * salt OCTET STRING, + * owf AlgorithmIdentifier, + * -- AlgId for a One-Way Function (SHA-1 recommended) + * iterationCount INTEGER, + * -- number of times the OWF is applied + * mac AlgorithmIdentifier + * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], + * -- or HMAC [HMAC, RFC2202]) + * } + */ +struct OSSL_crmf_pbmparameter_st { + ASN1_OCTET_STRING *salt; + X509_ALGOR *owf; + ASN1_INTEGER *iterationCount; + X509_ALGOR *mac; +} /* OSSL_CRMF_PBMPARAMETER */; +#define OSSL_CRMF_PBM_MAX_ITERATION_COUNT 100000 /* if too large allows DoS */ + +/*- + * POPOSigningKeyInput ::= SEQUENCE { + * authInfo CHOICE { + * sender [0] GeneralName, + * -- used only if an authenticated identity has been + * -- established for the sender (e.g., a DN from a + * -- previously-issued and currently-valid certificate) + * publicKeyMAC PKMACValue }, + * -- used if no authenticated GeneralName currently exists for + * -- the sender; publicKeyMAC contains a password-based MAC + * -- on the DER-encoded value of publicKey + * publicKey SubjectPublicKeyInfo -- from CertTemplate + * } +*/ +typedef struct OSSL_crmf_poposigningkeyinput_authinfo_st { + int type; + union { + /* 0 */ GENERAL_NAME *sender; + /* 1 */ OSSL_CRMF_PKMACVALUE *publicKeyMAC; + } value; +} OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) + +typedef struct OSSL_crmf_poposigningkeyinput_st { + OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO *authInfo; + X509_PUBKEY *publicKey; +} OSSL_CRMF_POPOSIGNINGKEYINPUT; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT) + +/*- + * POPOSigningKey ::= SEQUENCE { + * poposkInput [0] POPOSigningKeyInput OPTIONAL, + * algorithmIdentifier AlgorithmIdentifier, + * signature BIT STRING + * } + */ +struct OSSL_crmf_poposigningkey_st { + OSSL_CRMF_POPOSIGNINGKEYINPUT *poposkInput; + X509_ALGOR *algorithmIdentifier; + ASN1_BIT_STRING *signature; +} /* OSSL_CRMF_POPOSIGNINGKEY */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEY) + +/*- + * ProofOfPossession ::= CHOICE { + * raVerified [0] NULL, + * -- used if the RA has already verified that the requester is in + * -- possession of the private key + * signature [1] POPOSigningKey, + * keyEncipherment [2] POPOPrivKey, + * keyAgreement [3] POPOPrivKey + * } + */ +typedef struct OSSL_crmf_popo_st { + int type; + union { + ASN1_NULL *raVerified; /* 0 */ + OSSL_CRMF_POPOSIGNINGKEY *signature; /* 1 */ + OSSL_CRMF_POPOPRIVKEY *keyEncipherment; /* 2 */ + OSSL_CRMF_POPOPRIVKEY *keyAgreement; /* 3 */ + } value; +} OSSL_CRMF_POPO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPO) + +/*- + * OptionalValidity ::= SEQUENCE { + * notBefore [0] Time OPTIONAL, + * notAfter [1] Time OPTIONAL -- at least one MUST be present + * } + */ +struct OSSL_crmf_optionalvalidity_st { + /* 0 */ ASN1_TIME *notBefore; + /* 1 */ ASN1_TIME *notAfter; +} /* OSSL_CRMF_OPTIONALVALIDITY */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_OPTIONALVALIDITY) + +/*- + * CertTemplate ::= SEQUENCE { + * version [0] Version OPTIONAL, + * serialNumber [1] INTEGER OPTIONAL, + * signingAlg [2] AlgorithmIdentifier OPTIONAL, + * issuer [3] Name OPTIONAL, + * validity [4] OptionalValidity OPTIONAL, + * subject [5] Name OPTIONAL, + * publicKey [6] SubjectPublicKeyInfo OPTIONAL, + * issuerUID [7] UniqueIdentifier OPTIONAL, + * subjectUID [8] UniqueIdentifier OPTIONAL, + * extensions [9] Extensions OPTIONAL + * } + */ +struct OSSL_crmf_certtemplate_st { + ASN1_INTEGER *version; /* 0 */ + ASN1_INTEGER *serialNumber; /* 1 */ /* serialNumber MUST be omitted */ + /* This field is assigned by the CA during certificate creation */ + X509_ALGOR *signingAlg; /* 2 */ /* signingAlg MUST be omitted */ + /* This field is assigned by the CA during certificate creation */ + X509_NAME *issuer; /* 3 */ + OSSL_CRMF_OPTIONALVALIDITY *validity; /* 4 */ + X509_NAME *subject; /* 5 */ + X509_PUBKEY *publicKey; /* 6 */ + ASN1_BIT_STRING *issuerUID; /* 7 */ /* deprecated in version 2 */ + /* According to rfc 3280: UniqueIdentifier ::= BIT STRING */ + ASN1_BIT_STRING *subjectUID; /* 8 */ /* deprecated in version 2 */ + /* Could be X509_EXTENSION*S*, but that's only cosmetic */ + STACK_OF(X509_EXTENSION) *extensions; /* 9 */ +} /* OSSL_CRMF_CERTTEMPLATE */; + +/*- + * CertRequest ::= SEQUENCE { + * certReqId INTEGER, -- ID for matching request and reply + * certTemplate CertTemplate, -- Selected fields of cert to be issued + * controls Controls OPTIONAL -- Attributes affecting issuance + * } + */ +struct OSSL_crmf_certrequest_st { + ASN1_INTEGER *certReqId; + OSSL_CRMF_CERTTEMPLATE *certTemplate; + /* TODO: make OSSL_CRMF_CONTROLS out of that - but only cosmetical */ + STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *controls; +} /* OSSL_CRMF_CERTREQUEST */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST) + +/* TODO: isn't there a better way to have this for ANY type? */ +struct OSSL_crmf_attributetypeandvalue_st { + ASN1_OBJECT *type; + union { + /* NID_id_regCtrl_regToken */ + ASN1_UTF8STRING *regToken; + + /* NID_id_regCtrl_authenticator */ + ASN1_UTF8STRING *authenticator; + + /* NID_id_regCtrl_pkiPublicationInfo */ + OSSL_CRMF_PKIPUBLICATIONINFO *pkiPublicationInfo; + + /* NID_id_regCtrl_oldCertID */ + OSSL_CRMF_CERTID *oldCertID; + + /* NID_id_regCtrl_protocolEncrKey */ + X509_PUBKEY *protocolEncrKey; + + /* NID_id_regInfo_utf8Pairs */ + ASN1_UTF8STRING *utf8Pairs; + + /* NID_id_regInfo_certReq */ + OSSL_CRMF_CERTREQUEST *certReq; + + ASN1_TYPE *other; + } value; +} /* OSSL_CRMF_ATTRIBUTETYPEANDVALUE */; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +DEFINE_STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) + +/*- + * CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg + * CertReqMsg ::= SEQUENCE { + * certReq CertRequest, + * popo ProofOfPossession OPTIONAL, + * -- content depends upon key type + * regInfo SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL + * } + */ +struct OSSL_crmf_msg_st { + OSSL_CRMF_CERTREQUEST *certReq; + /* 0 */ + OSSL_CRMF_POPO *popo; + /* 1 */ + STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *regInfo; +} /* OSSL_CRMF_MSG */; +/* DEFINE_STACK_OF(OSSL_CRMF_MSG) */ +#endif diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c new file mode 100644 index 0000000000..49deca75f8 --- /dev/null +++ b/crypto/crmf/crmf_lib.c @@ -0,0 +1,753 @@ +/*- + * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2018 + * Copyright Siemens AG 2015-2018 + * + * Licensed under the OpenSSL license (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 + * + * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. + */ + +/* + * This file contains the functions that handle the individual items inside + * the CRMF structures + */ + +/* + * NAMING + * + * The 0 functions use the supplied structure pointer directly in the parent and + * it will be freed up when the parent is freed. + * + * The 1 functions use a copy of the supplied structure pointer (or in some + * cases increases its link count) in the parent and so both should be freed up. + */ + +#include <openssl/asn1t.h> + +#include "crmf_int.h" + +/* explicit #includes not strictly needed since implied by the above: */ +#include <openssl/crmf.h> +#include <openssl/err.h> +#includ |