| 1 | /*- |
| 2 | * Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. |
| 3 | * Copyright Nokia 2007-2019 |
| 4 | * Copyright Siemens AG 2015-2019 |
| 5 | * |
| 6 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
| 7 | * this file except in compliance with the License. You can obtain a copy |
| 8 | * in the file LICENSE in the source distribution or at |
| 9 | * https://www.openssl.org/source/license.html |
| 10 | * |
| 11 | * CRMF implementation by Martin Peylo, Miikka Viljanen, and David von Oheimb. |
| 12 | */ |
| 13 | |
| 14 | #ifndef OSSL_CRYPTO_CRMF_LOCAL_H |
| 15 | # define OSSL_CRYPTO_CRMF_LOCAL_H |
| 16 | |
| 17 | # include <openssl/crmf.h> |
| 18 | # include <openssl/err.h> |
| 19 | |
| 20 | /* explicit #includes not strictly needed since implied by the above: */ |
| 21 | # include <openssl/types.h> |
| 22 | # include <openssl/safestack.h> |
| 23 | # include <openssl/x509.h> |
| 24 | # include <openssl/x509v3.h> |
| 25 | |
| 26 | /*- |
| 27 | * EncryptedValue ::= SEQUENCE { |
| 28 | * intendedAlg [0] AlgorithmIdentifier OPTIONAL, |
| 29 | * -- the intended algorithm for which the value will be used |
| 30 | * symmAlg [1] AlgorithmIdentifier OPTIONAL, |
| 31 | * -- the symmetric algorithm used to encrypt the value |
| 32 | * encSymmKey [2] BIT STRING OPTIONAL, |
| 33 | * -- the (encrypted) symmetric key used to encrypt the value |
| 34 | * keyAlg [3] AlgorithmIdentifier OPTIONAL, |
| 35 | * -- algorithm used to encrypt the symmetric key |
| 36 | * valueHint [4] OCTET STRING OPTIONAL, |
| 37 | * -- a brief description or identifier of the encValue content |
| 38 | * -- (may be meaningful only to the sending entity, and |
| 39 | * -- used only if EncryptedValue might be re-examined |
| 40 | * -- by the sending entity in the future) |
| 41 | * encValue BIT STRING |
| 42 | * -- the encrypted value itself |
| 43 | * } |
| 44 | */ |
| 45 | struct ossl_crmf_encryptedvalue_st { |
| 46 | X509_ALGOR *intendedAlg; /* 0 */ |
| 47 | X509_ALGOR *symmAlg; /* 1 */ |
| 48 | ASN1_BIT_STRING *encSymmKey; /* 2 */ |
| 49 | X509_ALGOR *keyAlg; /* 3 */ |
| 50 | ASN1_OCTET_STRING *valueHint; /* 4 */ |
| 51 | ASN1_BIT_STRING *encValue; |
| 52 | } /* OSSL_CRMF_ENCRYPTEDVALUE */; |
| 53 | |
| 54 | /*- |
| 55 | * Attributes ::= SET OF Attribute |
| 56 | * => X509_ATTRIBUTE |
| 57 | * |
| 58 | * PrivateKeyInfo ::= SEQUENCE { |
| 59 | * version INTEGER, |
| 60 | * privateKeyAlgorithm AlgorithmIdentifier, |
| 61 | * privateKey OCTET STRING, |
| 62 | * attributes [0] IMPLICIT Attributes OPTIONAL |
| 63 | * } |
| 64 | */ |
| 65 | typedef struct ossl_crmf_privatekeyinfo_st { |
| 66 | ASN1_INTEGER *version; |
| 67 | X509_ALGOR *privateKeyAlgorithm; |
| 68 | ASN1_OCTET_STRING *privateKey; |
| 69 | STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ |
| 70 | } OSSL_CRMF_PRIVATEKEYINFO; |
| 71 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PRIVATEKEYINFO) |
| 72 | |
| 73 | /*- |
| 74 | * section 4.2.1 Private Key Info Content Type |
| 75 | * id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} |
| 76 | * |
| 77 | * EncKeyWithID ::= SEQUENCE { |
| 78 | * privateKey PrivateKeyInfo, |
| 79 | * identifier CHOICE { |
| 80 | * string UTF8String, |
| 81 | * generalName GeneralName |
| 82 | * } OPTIONAL |
| 83 | * } |
| 84 | */ |
| 85 | typedef struct ossl_crmf_enckeywithid_identifier_st { |
| 86 | int type; |
| 87 | union { |
| 88 | ASN1_UTF8STRING *string; |
| 89 | GENERAL_NAME *generalName; |
| 90 | } value; |
| 91 | } OSSL_CRMF_ENCKEYWITHID_IDENTIFIER; |
| 92 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID_IDENTIFIER) |
| 93 | |
| 94 | typedef struct ossl_crmf_enckeywithid_st { |
| 95 | OSSL_CRMF_PRIVATEKEYINFO *privateKey; |
| 96 | /* [0] */ |
| 97 | OSSL_CRMF_ENCKEYWITHID_IDENTIFIER *identifier; |
| 98 | } OSSL_CRMF_ENCKEYWITHID; |
| 99 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCKEYWITHID) |
| 100 | |
| 101 | /*- |
| 102 | * CertId ::= SEQUENCE { |
| 103 | * issuer GeneralName, |
| 104 | * serialNumber INTEGER |
| 105 | * } |
| 106 | */ |
| 107 | struct ossl_crmf_certid_st { |
| 108 | GENERAL_NAME *issuer; |
| 109 | ASN1_INTEGER *serialNumber; |
| 110 | } /* OSSL_CRMF_CERTID */; |
| 111 | DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) |
| 112 | |
| 113 | /*- |
| 114 | * SinglePubInfo ::= SEQUENCE { |
| 115 | * pubMethod INTEGER { |
| 116 | * dontCare (0), |
| 117 | * x500 (1), |
| 118 | * web (2), |
| 119 | * ldap (3) }, |
| 120 | * pubLocation GeneralName OPTIONAL |
| 121 | * } |
| 122 | */ |
| 123 | struct ossl_crmf_singlepubinfo_st { |
| 124 | ASN1_INTEGER *pubMethod; |
| 125 | GENERAL_NAME *pubLocation; |
| 126 | } /* OSSL_CRMF_SINGLEPUBINFO */; |
| 127 | DEFINE_STACK_OF(OSSL_CRMF_SINGLEPUBINFO) |
| 128 | typedef STACK_OF(OSSL_CRMF_SINGLEPUBINFO) OSSL_CRMF_PUBINFOS; |
| 129 | |
| 130 | |
| 131 | /*- |
| 132 | * PKIPublicationInfo ::= SEQUENCE { |
| 133 | * action INTEGER { |
| 134 | * dontPublish (0), |
| 135 | * pleasePublish (1) }, |
| 136 | * pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL |
| 137 | * -- pubInfos MUST NOT be present if action is "dontPublish" |
| 138 | * -- (if action is "pleasePublish" and pubInfos is omitted, |
| 139 | * -- "dontCare" is assumed) |
| 140 | * } |
| 141 | */ |
| 142 | struct ossl_crmf_pkipublicationinfo_st { |
| 143 | ASN1_INTEGER *action; |
| 144 | OSSL_CRMF_PUBINFOS *pubInfos; |
| 145 | } /* OSSL_CRMF_PKIPUBLICATIONINFO */; |
| 146 | DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_PKIPUBLICATIONINFO) |
| 147 | |
| 148 | /*- |
| 149 | * PKMACValue ::= SEQUENCE { |
| 150 | * algId AlgorithmIdentifier, |
| 151 | * -- algorithm value shall be PasswordBasedMac {1 2 840 113533 7 66 13} |
| 152 | * -- parameter value is PBMParameter |
| 153 | * value BIT STRING |
| 154 | * } |
| 155 | */ |
| 156 | typedef struct ossl_crmf_pkmacvalue_st { |
| 157 | X509_ALGOR *algId; |
| 158 | ASN1_BIT_STRING *value; |
| 159 | } OSSL_CRMF_PKMACVALUE; |
| 160 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PKMACVALUE) |
| 161 | |
| 162 | /*- |
| 163 | * SubsequentMessage ::= INTEGER { |
| 164 | * encrCert (0), |
| 165 | * -- requests that resulting certificate be encrypted for the |
| 166 | * -- end entity (following which, POP will be proven in a |
| 167 | * -- confirmation message) |
| 168 | * challengeResp (1) |
| 169 | * -- requests that CA engage in challenge-response exchange with |
| 170 | * -- end entity in order to prove private key possession |
| 171 | * } |
| 172 | * |
| 173 | * POPOPrivKey ::= CHOICE { |
| 174 | * thisMessage [0] BIT STRING, -- Deprecated |
| 175 | * -- possession is proven in this message (which contains the private |
| 176 | * -- key itself (encrypted for the CA)) |
| 177 | * subsequentMessage [1] SubsequentMessage, |
| 178 | * -- possession will be proven in a subsequent message |
| 179 | * dhMAC [2] BIT STRING, -- Deprecated |
| 180 | * agreeMAC [3] PKMACValue, |
| 181 | * encryptedKey [4] EnvelopedData |
| 182 | * } |
| 183 | */ |
| 184 | |
| 185 | typedef struct ossl_crmf_popoprivkey_st { |
| 186 | int type; |
| 187 | union { |
| 188 | ASN1_BIT_STRING *thisMessage; /* 0 */ /* Deprecated */ |
| 189 | ASN1_INTEGER *subsequentMessage; /* 1 */ |
| 190 | ASN1_BIT_STRING *dhMAC; /* 2 */ /* Deprecated */ |
| 191 | OSSL_CRMF_PKMACVALUE *agreeMAC; /* 3 */ |
| 192 | /* |
| 193 | * TODO: This is not ASN1_NULL but CMS_ENVELOPEDDATA which should be |
| 194 | * somehow taken from crypto/cms which exists now |
| 195 | * - this is not used anywhere so far |
| 196 | */ |
| 197 | ASN1_NULL *encryptedKey; /* 4 */ |
| 198 | } value; |
| 199 | } OSSL_CRMF_POPOPRIVKEY; |
| 200 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOPRIVKEY) |
| 201 | |
| 202 | /*- |
| 203 | * PBMParameter ::= SEQUENCE { |
| 204 | * salt OCTET STRING, |
| 205 | * owf AlgorithmIdentifier, |
| 206 | * -- AlgId for a One-Way Function (SHA-1 recommended) |
| 207 | * iterationCount INTEGER, |
| 208 | * -- number of times the OWF is applied |
| 209 | * mac AlgorithmIdentifier |
| 210 | * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], |
| 211 | * -- or HMAC [HMAC, RFC2202]) |
| 212 | * } |
| 213 | */ |
| 214 | struct ossl_crmf_pbmparameter_st { |
| 215 | ASN1_OCTET_STRING *salt; |
| 216 | X509_ALGOR *owf; |
| 217 | ASN1_INTEGER *iterationCount; |
| 218 | X509_ALGOR *mac; |
| 219 | } /* OSSL_CRMF_PBMPARAMETER */; |
| 220 | # define OSSL_CRMF_PBM_MAX_ITERATION_COUNT 100000 /* if too large allows DoS */ |
| 221 | |
| 222 | /*- |
| 223 | * POPOSigningKeyInput ::= SEQUENCE { |
| 224 | * authInfo CHOICE { |
| 225 | * sender [0] GeneralName, |
| 226 | * -- used only if an authenticated identity has been |
| 227 | * -- established for the sender (e.g., a DN from a |
| 228 | * -- previously-issued and currently-valid certificate) |
| 229 | * publicKeyMAC PKMACValue }, |
| 230 | * -- used if no authenticated GeneralName currently exists for |
| 231 | * -- the sender; publicKeyMAC contains a password-based MAC |
| 232 | * -- on the DER-encoded value of publicKey |
| 233 | * publicKey SubjectPublicKeyInfo -- from CertTemplate |
| 234 | * } |
| 235 | */ |
| 236 | typedef struct ossl_crmf_poposigningkeyinput_authinfo_st { |
| 237 | int type; |
| 238 | union { |
| 239 | /* 0 */ GENERAL_NAME *sender; |
| 240 | /* 1 */ OSSL_CRMF_PKMACVALUE *publicKeyMAC; |
| 241 | } value; |
| 242 | } OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO; |
| 243 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO) |
| 244 | |
| 245 | typedef struct ossl_crmf_poposigningkeyinput_st { |
| 246 | OSSL_CRMF_POPOSIGNINGKEYINPUT_AUTHINFO *authInfo; |
| 247 | X509_PUBKEY *publicKey; |
| 248 | } OSSL_CRMF_POPOSIGNINGKEYINPUT; |
| 249 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEYINPUT) |
| 250 | |
| 251 | /*- |
| 252 | * POPOSigningKey ::= SEQUENCE { |
| 253 | * poposkInput [0] POPOSigningKeyInput OPTIONAL, |
| 254 | * algorithmIdentifier AlgorithmIdentifier, |
| 255 | * signature BIT STRING |
| 256 | * } |
| 257 | */ |
| 258 | struct ossl_crmf_poposigningkey_st { |
| 259 | OSSL_CRMF_POPOSIGNINGKEYINPUT *poposkInput; |
| 260 | X509_ALGOR *algorithmIdentifier; |
| 261 | ASN1_BIT_STRING *signature; |
| 262 | } /* OSSL_CRMF_POPOSIGNINGKEY */; |
| 263 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPOSIGNINGKEY) |
| 264 | |
| 265 | /*- |
| 266 | * ProofOfPossession ::= CHOICE { |
| 267 | * raVerified [0] NULL, |
| 268 | * -- used if the RA has already verified that the requester is in |
| 269 | * -- possession of the private key |
| 270 | * signature [1] POPOSigningKey, |
| 271 | * keyEncipherment [2] POPOPrivKey, |
| 272 | * keyAgreement [3] POPOPrivKey |
| 273 | * } |
| 274 | */ |
| 275 | typedef struct ossl_crmf_popo_st { |
| 276 | int type; |
| 277 | union { |
| 278 | ASN1_NULL *raVerified; /* 0 */ |
| 279 | OSSL_CRMF_POPOSIGNINGKEY *signature; /* 1 */ |
| 280 | OSSL_CRMF_POPOPRIVKEY *keyEncipherment; /* 2 */ |
| 281 | OSSL_CRMF_POPOPRIVKEY *keyAgreement; /* 3 */ |
| 282 | } value; |
| 283 | } OSSL_CRMF_POPO; |
| 284 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_POPO) |
| 285 | |
| 286 | /*- |
| 287 | * OptionalValidity ::= SEQUENCE { |
| 288 | * notBefore [0] Time OPTIONAL, |
| 289 | * notAfter [1] Time OPTIONAL -- at least one MUST be present |
| 290 | * } |
| 291 | */ |
| 292 | struct ossl_crmf_optionalvalidity_st { |
| 293 | /* 0 */ ASN1_TIME *notBefore; |
| 294 | /* 1 */ ASN1_TIME *notAfter; |
| 295 | } /* OSSL_CRMF_OPTIONALVALIDITY */; |
| 296 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_OPTIONALVALIDITY) |
| 297 | |
| 298 | /*- |
| 299 | * CertTemplate ::= SEQUENCE { |
| 300 | * version [0] Version OPTIONAL, |
| 301 | * serialNumber [1] INTEGER OPTIONAL, |
| 302 | * signingAlg [2] AlgorithmIdentifier OPTIONAL, |
| 303 | * issuer [3] Name OPTIONAL, |
| 304 | * validity [4] OptionalValidity OPTIONAL, |
| 305 | * subject [5] Name OPTIONAL, |
| 306 | * publicKey [6] SubjectPublicKeyInfo OPTIONAL, |
| 307 | * issuerUID [7] UniqueIdentifier OPTIONAL, |
| 308 | * subjectUID [8] UniqueIdentifier OPTIONAL, |
| 309 | * extensions [9] Extensions OPTIONAL |
| 310 | * } |
| 311 | */ |
| 312 | struct ossl_crmf_certtemplate_st { |
| 313 | ASN1_INTEGER *version; /* 0 */ |
| 314 | ASN1_INTEGER *serialNumber; /* 1 */ /* serialNumber MUST be omitted */ |
| 315 | /* This field is assigned by the CA during certificate creation */ |
| 316 | X509_ALGOR *signingAlg; /* 2 */ /* signingAlg MUST be omitted */ |
| 317 | /* This field is assigned by the CA during certificate creation */ |
| 318 | X509_NAME *issuer; /* 3 */ |
| 319 | OSSL_CRMF_OPTIONALVALIDITY *validity; /* 4 */ |
| 320 | X509_NAME *subject; /* 5 */ |
| 321 | X509_PUBKEY *publicKey; /* 6 */ |
| 322 | ASN1_BIT_STRING *issuerUID; /* 7 */ /* deprecated in version 2 */ |
| 323 | /* According to rfc 3280: UniqueIdentifier ::= BIT STRING */ |
| 324 | ASN1_BIT_STRING *subjectUID; /* 8 */ /* deprecated in version 2 */ |
| 325 | /* Could be X509_EXTENSION*S*, but that's only cosmetic */ |
| 326 | STACK_OF(X509_EXTENSION) *extensions; /* 9 */ |
| 327 | } /* OSSL_CRMF_CERTTEMPLATE */; |
| 328 | |
| 329 | /*- |
| 330 | * CertRequest ::= SEQUENCE { |
| 331 | * certReqId INTEGER, -- ID for matching request and reply |
| 332 | * certTemplate CertTemplate, -- Selected fields of cert to be issued |
| 333 | * controls Controls OPTIONAL -- Attributes affecting issuance |
| 334 | * } |
| 335 | */ |
| 336 | struct ossl_crmf_certrequest_st { |
| 337 | ASN1_INTEGER *certReqId; |
| 338 | OSSL_CRMF_CERTTEMPLATE *certTemplate; |
| 339 | /* TODO: make OSSL_CRMF_CONTROLS out of that - but only cosmetical */ |
| 340 | STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *controls; |
| 341 | } /* OSSL_CRMF_CERTREQUEST */; |
| 342 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTREQUEST) |
| 343 | DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTREQUEST) |
| 344 | |
| 345 | /* TODO: isn't there a better way to have this for ANY type? */ |
| 346 | struct ossl_crmf_attributetypeandvalue_st { |
| 347 | ASN1_OBJECT *type; |
| 348 | union { |
| 349 | /* NID_id_regCtrl_regToken */ |
| 350 | ASN1_UTF8STRING *regToken; |
| 351 | |
| 352 | /* NID_id_regCtrl_authenticator */ |
| 353 | ASN1_UTF8STRING *authenticator; |
| 354 | |
| 355 | /* NID_id_regCtrl_pkiPublicationInfo */ |
| 356 | OSSL_CRMF_PKIPUBLICATIONINFO *pkiPublicationInfo; |
| 357 | |
| 358 | /* NID_id_regCtrl_oldCertID */ |
| 359 | OSSL_CRMF_CERTID *oldCertID; |
| 360 | |
| 361 | /* NID_id_regCtrl_protocolEncrKey */ |
| 362 | X509_PUBKEY *protocolEncrKey; |
| 363 | |
| 364 | /* NID_id_regInfo_utf8Pairs */ |
| 365 | ASN1_UTF8STRING *utf8Pairs; |
| 366 | |
| 367 | /* NID_id_regInfo_certReq */ |
| 368 | OSSL_CRMF_CERTREQUEST *certReq; |
| 369 | |
| 370 | ASN1_TYPE *other; |
| 371 | } value; |
| 372 | } /* OSSL_CRMF_ATTRIBUTETYPEANDVALUE */; |
| 373 | DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) |
| 374 | DEFINE_STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) |
| 375 | DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) |
| 376 | |
| 377 | /*- |
| 378 | * CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg |
| 379 | * CertReqMsg ::= SEQUENCE { |
| 380 | * certReq CertRequest, |
| 381 | * popo ProofOfPossession OPTIONAL, |
| 382 | * -- content depends upon key type |
| 383 | * regInfo SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL |
| 384 | * } |
| 385 | */ |
| 386 | struct ossl_crmf_msg_st { |
| 387 | OSSL_CRMF_CERTREQUEST *certReq; |
| 388 | /* 0 */ |
| 389 | OSSL_CRMF_POPO *popo; |
| 390 | /* 1 */ |
| 391 | STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *regInfo; |
| 392 | } /* OSSL_CRMF_MSG */; |
| 393 | /* DEFINE_STACK_OF(OSSL_CRMF_MSG) */ |
| 394 | #endif |
| 395 | |