diff options
Diffstat (limited to 'src/lib/libssl/src/crypto/cms/cms_lib.c')
| -rw-r--r-- | src/lib/libssl/src/crypto/cms/cms_lib.c | 445 |
1 files changed, 209 insertions, 236 deletions
diff --git a/src/lib/libssl/src/crypto/cms/cms_lib.c b/src/lib/libssl/src/crypto/cms/cms_lib.c index ba08279a04..66bd73c86c 100644 --- a/src/lib/libssl/src/crypto/cms/cms_lib.c +++ b/src/lib/libssl/src/crypto/cms/cms_lib.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | * are met: | 10 | * are met: |
| 11 | * | 11 | * |
| 12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. |
| 14 | * | 14 | * |
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
| 16 | * notice, this list of conditions and the following disclaimer in | 16 | * notice, this list of conditions and the following disclaimer in |
| @@ -68,27 +68,31 @@ DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) | |||
| 68 | DECLARE_STACK_OF(CMS_CertificateChoices) | 68 | DECLARE_STACK_OF(CMS_CertificateChoices) |
| 69 | DECLARE_STACK_OF(CMS_RevocationInfoChoice) | 69 | DECLARE_STACK_OF(CMS_RevocationInfoChoice) |
| 70 | 70 | ||
| 71 | const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms) | 71 | const ASN1_OBJECT * |
| 72 | { | 72 | CMS_get0_type(CMS_ContentInfo *cms) |
| 73 | { | ||
| 73 | return cms->contentType; | 74 | return cms->contentType; |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | CMS_ContentInfo *cms_Data_create(void) | 77 | CMS_ContentInfo * |
| 77 | { | 78 | cms_Data_create(void) |
| 79 | { | ||
| 78 | CMS_ContentInfo *cms; | 80 | CMS_ContentInfo *cms; |
| 81 | |||
| 79 | cms = CMS_ContentInfo_new(); | 82 | cms = CMS_ContentInfo_new(); |
| 80 | if (cms) | 83 | if (cms) { |
| 81 | { | ||
| 82 | cms->contentType = OBJ_nid2obj(NID_pkcs7_data); | 84 | cms->contentType = OBJ_nid2obj(NID_pkcs7_data); |
| 83 | /* Never detached */ | 85 | /* Never detached */ |
| 84 | CMS_set_detached(cms, 0); | 86 | CMS_set_detached(cms, 0); |
| 85 | } | ||
| 86 | return cms; | ||
| 87 | } | 87 | } |
| 88 | return cms; | ||
| 89 | } | ||
| 88 | 90 | ||
| 89 | BIO *cms_content_bio(CMS_ContentInfo *cms) | 91 | BIO * |
| 90 | { | 92 | cms_content_bio(CMS_ContentInfo *cms) |
| 93 | { | ||
| 91 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); | 94 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); |
| 95 | |||
| 92 | if (!pos) | 96 | if (!pos) |
| 93 | return NULL; | 97 | return NULL; |
| 94 | /* If content detached data goes nowhere: create NULL BIO */ | 98 | /* If content detached data goes nowhere: create NULL BIO */ |
| @@ -100,51 +104,45 @@ BIO *cms_content_bio(CMS_ContentInfo *cms) | |||
| 100 | return BIO_new(BIO_s_mem()); | 104 | return BIO_new(BIO_s_mem()); |
| 101 | /* Else content was read in: return read only BIO for it */ | 105 | /* Else content was read in: return read only BIO for it */ |
| 102 | return BIO_new_mem_buf((*pos)->data, (*pos)->length); | 106 | return BIO_new_mem_buf((*pos)->data, (*pos)->length); |
| 103 | } | 107 | } |
| 104 | 108 | ||
| 105 | BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) | 109 | BIO * |
| 106 | { | 110 | CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) |
| 111 | { | ||
| 107 | BIO *cmsbio, *cont; | 112 | BIO *cmsbio, *cont; |
| 113 | |||
| 108 | if (icont) | 114 | if (icont) |
| 109 | cont = icont; | 115 | cont = icont; |
| 110 | else | 116 | else |
| 111 | cont = cms_content_bio(cms); | 117 | cont = cms_content_bio(cms); |
| 112 | if (!cont) | 118 | if (!cont) { |
| 113 | { | ||
| 114 | CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); | 119 | CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); |
| 115 | return NULL; | 120 | return NULL; |
| 116 | } | 121 | } |
| 117 | switch (OBJ_obj2nid(cms->contentType)) | 122 | switch (OBJ_obj2nid(cms->contentType)) { |
| 118 | { | 123 | case NID_pkcs7_data: |
| 119 | |||
| 120 | case NID_pkcs7_data: | ||
| 121 | return cont; | 124 | return cont; |
| 122 | 125 | case NID_pkcs7_signed: | |
| 123 | case NID_pkcs7_signed: | ||
| 124 | cmsbio = cms_SignedData_init_bio(cms); | 126 | cmsbio = cms_SignedData_init_bio(cms); |
| 125 | break; | 127 | break; |
| 126 | 128 | case NID_pkcs7_digest: | |
| 127 | case NID_pkcs7_digest: | ||
| 128 | cmsbio = cms_DigestedData_init_bio(cms); | 129 | cmsbio = cms_DigestedData_init_bio(cms); |
| 129 | break; | 130 | break; |
| 130 | #ifdef ZLIB | 131 | #ifdef ZLIB |
| 131 | case NID_id_smime_ct_compressedData: | 132 | case NID_id_smime_ct_compressedData: |
| 132 | cmsbio = cms_CompressedData_init_bio(cms); | 133 | cmsbio = cms_CompressedData_init_bio(cms); |
| 133 | break; | 134 | break; |
| 134 | #endif | 135 | #endif |
| 135 | 136 | case NID_pkcs7_encrypted: | |
| 136 | case NID_pkcs7_encrypted: | ||
| 137 | cmsbio = cms_EncryptedData_init_bio(cms); | 137 | cmsbio = cms_EncryptedData_init_bio(cms); |
| 138 | break; | 138 | break; |
| 139 | 139 | case NID_pkcs7_enveloped: | |
| 140 | case NID_pkcs7_enveloped: | ||
| 141 | cmsbio = cms_EnvelopedData_init_bio(cms); | 140 | cmsbio = cms_EnvelopedData_init_bio(cms); |
| 142 | break; | 141 | break; |
| 143 | 142 | default: | |
| 144 | default: | ||
| 145 | CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); | 143 | CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); |
| 146 | return NULL; | 144 | return NULL; |
| 147 | } | 145 | } |
| 148 | 146 | ||
| 149 | if (cmsbio) | 147 | if (cmsbio) |
| 150 | return BIO_push(cmsbio, cont); | 148 | return BIO_push(cmsbio, cont); |
| @@ -152,142 +150,121 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) | |||
| 152 | if (!icont) | 150 | if (!icont) |
| 153 | BIO_free(cont); | 151 | BIO_free(cont); |
| 154 | return NULL; | 152 | return NULL; |
| 153 | } | ||
| 155 | 154 | ||
| 156 | } | 155 | int |
| 157 | 156 | CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) | |
| 158 | int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) | 157 | { |
| 159 | { | ||
| 160 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); | 158 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); |
| 159 | |||
| 161 | if (!pos) | 160 | if (!pos) |
| 162 | return 0; | 161 | return 0; |
| 163 | /* If ebmedded content find memory BIO and set content */ | 162 | /* If ebmedded content find memory BIO and set content */ |
| 164 | if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) | 163 | if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { |
| 165 | { | ||
| 166 | BIO *mbio; | 164 | BIO *mbio; |
| 167 | unsigned char *cont; | 165 | unsigned char *cont; |
| 168 | long contlen; | 166 | long contlen; |
| 169 | mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); | 167 | mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); |
| 170 | if (!mbio) | 168 | if (!mbio) { |
| 171 | { | ||
| 172 | CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); | 169 | CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); |
| 173 | return 0; | 170 | return 0; |
| 174 | } | 171 | } |
| 175 | contlen = BIO_get_mem_data(mbio, &cont); | 172 | contlen = BIO_get_mem_data(mbio, &cont); |
| 176 | /* Set bio as read only so its content can't be clobbered */ | 173 | /* Set bio as read only so its content can't be clobbered */ |
| 177 | BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); | 174 | BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); |
| 178 | BIO_set_mem_eof_return(mbio, 0); | 175 | BIO_set_mem_eof_return(mbio, 0); |
| 179 | ASN1_STRING_set0(*pos, cont, contlen); | 176 | ASN1_STRING_set0(*pos, cont, contlen); |
| 180 | (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; | 177 | (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; |
| 181 | } | 178 | } |
| 182 | |||
| 183 | switch (OBJ_obj2nid(cms->contentType)) | ||
| 184 | { | ||
| 185 | 179 | ||
| 186 | case NID_pkcs7_data: | 180 | switch (OBJ_obj2nid(cms->contentType)) { |
| 187 | case NID_pkcs7_enveloped: | 181 | case NID_pkcs7_data: |
| 188 | case NID_pkcs7_encrypted: | 182 | case NID_pkcs7_enveloped: |
| 189 | case NID_id_smime_ct_compressedData: | 183 | case NID_pkcs7_encrypted: |
| 184 | case NID_id_smime_ct_compressedData: | ||
| 190 | /* Nothing to do */ | 185 | /* Nothing to do */ |
| 191 | return 1; | 186 | return 1; |
| 192 | 187 | case NID_pkcs7_signed: | |
| 193 | case NID_pkcs7_signed: | ||
| 194 | return cms_SignedData_final(cms, cmsbio); | 188 | return cms_SignedData_final(cms, cmsbio); |
| 195 | 189 | case NID_pkcs7_digest: | |
| 196 | case NID_pkcs7_digest: | ||
| 197 | return cms_DigestedData_do_final(cms, cmsbio, 0); | 190 | return cms_DigestedData_do_final(cms, cmsbio, 0); |
| 198 | 191 | default: | |
| 199 | default: | ||
| 200 | CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); | 192 | CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); |
| 201 | return 0; | 193 | return 0; |
| 202 | } | ||
| 203 | } | 194 | } |
| 195 | } | ||
| 204 | 196 | ||
| 205 | /* Return an OCTET STRING pointer to content. This allows it to | 197 | /* Return an OCTET STRING pointer to content. This allows it to |
| 206 | * be accessed or set later. | 198 | * be accessed or set later. |
| 207 | */ | 199 | */ |
| 208 | 200 | ||
| 209 | ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) | 201 | ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) |
| 210 | { | 202 | { |
| 211 | switch (OBJ_obj2nid(cms->contentType)) | 203 | switch (OBJ_obj2nid(cms->contentType)) { |
| 212 | { | 204 | case NID_pkcs7_data: |
| 213 | |||
| 214 | case NID_pkcs7_data: | ||
| 215 | return &cms->d.data; | 205 | return &cms->d.data; |
| 216 | 206 | case NID_pkcs7_signed: | |
| 217 | case NID_pkcs7_signed: | ||
| 218 | return &cms->d.signedData->encapContentInfo->eContent; | 207 | return &cms->d.signedData->encapContentInfo->eContent; |
| 219 | 208 | case NID_pkcs7_enveloped: | |
| 220 | case NID_pkcs7_enveloped: | ||
| 221 | return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; | 209 | return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; |
| 222 | 210 | case NID_pkcs7_digest: | |
| 223 | case NID_pkcs7_digest: | ||
| 224 | return &cms->d.digestedData->encapContentInfo->eContent; | 211 | return &cms->d.digestedData->encapContentInfo->eContent; |
| 225 | 212 | case NID_pkcs7_encrypted: | |
| 226 | case NID_pkcs7_encrypted: | ||
| 227 | return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; | 213 | return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; |
| 228 | 214 | case NID_id_smime_ct_authData: | |
| 229 | case NID_id_smime_ct_authData: | ||
| 230 | return &cms->d.authenticatedData->encapContentInfo->eContent; | 215 | return &cms->d.authenticatedData->encapContentInfo->eContent; |
| 231 | 216 | case NID_id_smime_ct_compressedData: | |
| 232 | case NID_id_smime_ct_compressedData: | ||
| 233 | return &cms->d.compressedData->encapContentInfo->eContent; | 217 | return &cms->d.compressedData->encapContentInfo->eContent; |
| 234 | 218 | default: | |
| 235 | default: | ||
| 236 | if (cms->d.other->type == V_ASN1_OCTET_STRING) | 219 | if (cms->d.other->type == V_ASN1_OCTET_STRING) |
| 237 | return &cms->d.other->value.octet_string; | 220 | return &cms->d.other->value.octet_string; |
| 238 | CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); | 221 | CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); |
| 239 | return NULL; | 222 | return NULL; |
| 240 | |||
| 241 | } | ||
| 242 | } | 223 | } |
| 224 | } | ||
| 243 | 225 | ||
| 244 | /* Return an ASN1_OBJECT pointer to content type. This allows it to | 226 | /* Return an ASN1_OBJECT pointer to content type. This allows it to |
| 245 | * be accessed or set later. | 227 | * be accessed or set later. |
| 246 | */ | 228 | */ |
| 247 | 229 | ||
| 248 | static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) | 230 | static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) |
| 249 | { | 231 | { |
| 250 | switch (OBJ_obj2nid(cms->contentType)) | 232 | switch (OBJ_obj2nid(cms->contentType)) { |
| 251 | { | 233 | case NID_pkcs7_signed: |
| 252 | |||
| 253 | case NID_pkcs7_signed: | ||
| 254 | return &cms->d.signedData->encapContentInfo->eContentType; | 234 | return &cms->d.signedData->encapContentInfo->eContentType; |
| 255 | 235 | case NID_pkcs7_enveloped: | |
| 256 | case NID_pkcs7_enveloped: | ||
| 257 | return &cms->d.envelopedData->encryptedContentInfo->contentType; | 236 | return &cms->d.envelopedData->encryptedContentInfo->contentType; |
| 258 | 237 | case NID_pkcs7_digest: | |
| 259 | case NID_pkcs7_digest: | ||
| 260 | return &cms->d.digestedData->encapContentInfo->eContentType; | 238 | return &cms->d.digestedData->encapContentInfo->eContentType; |
| 261 | 239 | case NID_pkcs7_encrypted: | |
| 262 | case NID_pkcs7_encrypted: | ||
| 263 | return &cms->d.encryptedData->encryptedContentInfo->contentType; | 240 | return &cms->d.encryptedData->encryptedContentInfo->contentType; |
| 264 | 241 | case NID_id_smime_ct_authData: | |
| 265 | case NID_id_smime_ct_authData: | ||
| 266 | return &cms->d.authenticatedData->encapContentInfo->eContentType; | 242 | return &cms->d.authenticatedData->encapContentInfo->eContentType; |
| 267 | 243 | case NID_id_smime_ct_compressedData: | |
| 268 | case NID_id_smime_ct_compressedData: | ||
| 269 | return &cms->d.compressedData->encapContentInfo->eContentType; | 244 | return &cms->d.compressedData->encapContentInfo->eContentType; |
| 270 | 245 | default: | |
| 271 | default: | ||
| 272 | CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, | 246 | CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, |
| 273 | CMS_R_UNSUPPORTED_CONTENT_TYPE); | 247 | CMS_R_UNSUPPORTED_CONTENT_TYPE); |
| 274 | return NULL; | 248 | return NULL; |
| 275 | |||
| 276 | } | ||
| 277 | } | 249 | } |
| 250 | } | ||
| 278 | 251 | ||
| 279 | const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) | 252 | const ASN1_OBJECT * |
| 280 | { | 253 | CMS_get0_eContentType(CMS_ContentInfo *cms) |
| 254 | { | ||
| 281 | ASN1_OBJECT **petype; | 255 | ASN1_OBJECT **petype; |
| 256 | |||
| 282 | petype = cms_get0_econtent_type(cms); | 257 | petype = cms_get0_econtent_type(cms); |
| 283 | if (petype) | 258 | if (petype) |
| 284 | return *petype; | 259 | return *petype; |
| 285 | return NULL; | 260 | return NULL; |
| 286 | } | 261 | } |
| 287 | 262 | ||
| 288 | int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) | 263 | int |
| 289 | { | 264 | CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) |
| 265 | { | ||
| 290 | ASN1_OBJECT **petype, *etype; | 266 | ASN1_OBJECT **petype, *etype; |
| 267 | |||
| 291 | petype = cms_get0_econtent_type(cms); | 268 | petype = cms_get0_econtent_type(cms); |
| 292 | if (!petype) | 269 | if (!petype) |
| 293 | return 0; | 270 | return 0; |
| @@ -299,52 +276,54 @@ int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) | |||
| 299 | ASN1_OBJECT_free(*petype); | 276 | ASN1_OBJECT_free(*petype); |
| 300 | *petype = etype; | 277 | *petype = etype; |
| 301 | return 1; | 278 | return 1; |
| 302 | } | 279 | } |
| 303 | 280 | ||
| 304 | int CMS_is_detached(CMS_ContentInfo *cms) | 281 | int |
| 305 | { | 282 | CMS_is_detached(CMS_ContentInfo *cms) |
| 283 | { | ||
| 306 | ASN1_OCTET_STRING **pos; | 284 | ASN1_OCTET_STRING **pos; |
| 285 | |||
| 307 | pos = CMS_get0_content(cms); | 286 | pos = CMS_get0_content(cms); |
| 308 | if (!pos) | 287 | if (!pos) |
| 309 | return -1; | 288 | return -1; |
| 310 | if (*pos) | 289 | if (*pos) |
| 311 | return 0; | 290 | return 0; |
| 312 | return 1; | 291 | return 1; |
| 313 | } | 292 | } |
| 314 | 293 | ||
| 315 | int CMS_set_detached(CMS_ContentInfo *cms, int detached) | 294 | int |
| 316 | { | 295 | CMS_set_detached(CMS_ContentInfo *cms, int detached) |
| 296 | { | ||
| 317 | ASN1_OCTET_STRING **pos; | 297 | ASN1_OCTET_STRING **pos; |
| 298 | |||
| 318 | pos = CMS_get0_content(cms); | 299 | pos = CMS_get0_content(cms); |
| 319 | if (!pos) | 300 | if (!pos) |
| 320 | return 0; | 301 | return 0; |
| 321 | if (detached) | 302 | if (detached) { |
| 322 | { | 303 | if (*pos) { |
| 323 | if (*pos) | ||
| 324 | { | ||
| 325 | ASN1_OCTET_STRING_free(*pos); | 304 | ASN1_OCTET_STRING_free(*pos); |
| 326 | *pos = NULL; | 305 | *pos = NULL; |
| 327 | } | ||
| 328 | return 1; | ||
| 329 | } | 306 | } |
| 307 | return 1; | ||
| 308 | } | ||
| 330 | if (!*pos) | 309 | if (!*pos) |
| 331 | *pos = ASN1_OCTET_STRING_new(); | 310 | *pos = ASN1_OCTET_STRING_new(); |
| 332 | if (*pos) | 311 | if (*pos) { |
| 333 | { | ||
| 334 | /* NB: special flag to show content is created and not | 312 | /* NB: special flag to show content is created and not |
| 335 | * read in. | 313 | * read in. |
| 336 | */ | 314 | */ |
| 337 | (*pos)->flags |= ASN1_STRING_FLAG_CONT; | 315 | (*pos)->flags |= ASN1_STRING_FLAG_CONT; |
| 338 | return 1; | 316 | return 1; |
| 339 | } | 317 | } |
| 340 | CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); | 318 | CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); |
| 341 | return 0; | 319 | return 0; |
| 342 | } | 320 | } |
| 343 | 321 | ||
| 344 | /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ | 322 | /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ |
| 345 | 323 | ||
| 346 | void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) | 324 | void |
| 347 | { | 325 | cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) |
| 326 | { | ||
| 348 | int param_type; | 327 | int param_type; |
| 349 | 328 | ||
| 350 | if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) | 329 | if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) |
| @@ -354,91 +333,90 @@ void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) | |||
| 354 | 333 | ||
| 355 | X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); | 334 | X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); |
| 356 | 335 | ||
| 357 | } | 336 | } |
| 358 | 337 | ||
| 359 | /* Create a digest BIO from an X509_ALGOR structure */ | 338 | /* Create a digest BIO from an X509_ALGOR structure */ |
| 360 | 339 | ||
| 361 | BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) | 340 | BIO * |
| 362 | { | 341 | cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) |
| 342 | { | ||
| 363 | BIO *mdbio = NULL; | 343 | BIO *mdbio = NULL; |
| 364 | ASN1_OBJECT *digestoid; | 344 | ASN1_OBJECT *digestoid; |
| 365 | const EVP_MD *digest; | 345 | const EVP_MD *digest; |
| 346 | |||
| 366 | X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); | 347 | X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); |
| 367 | digest = EVP_get_digestbyobj(digestoid); | 348 | digest = EVP_get_digestbyobj(digestoid); |
| 368 | if (!digest) | 349 | if (!digest) { |
| 369 | { | ||
| 370 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, | 350 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, |
| 371 | CMS_R_UNKNOWN_DIGEST_ALGORIHM); | 351 | CMS_R_UNKNOWN_DIGEST_ALGORIHM); |
| 372 | goto err; | 352 | goto err; |
| 373 | } | 353 | } |
| 374 | mdbio = BIO_new(BIO_f_md()); | 354 | mdbio = BIO_new(BIO_f_md()); |
| 375 | if (!mdbio || !BIO_set_md(mdbio, digest)) | 355 | if (!mdbio || !BIO_set_md(mdbio, digest)) { |
| 376 | { | ||
| 377 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, | 356 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, |
| 378 | CMS_R_MD_BIO_INIT_ERROR); | 357 | CMS_R_MD_BIO_INIT_ERROR); |
| 379 | goto err; | 358 | goto err; |
| 380 | } | 359 | } |
| 381 | return mdbio; | 360 | return mdbio; |
| 382 | err: | 361 | |
| 362 | err: | ||
| 383 | if (mdbio) | 363 | if (mdbio) |
| 384 | BIO_free(mdbio); | 364 | BIO_free(mdbio); |
| 385 | return NULL; | 365 | return NULL; |
| 386 | } | 366 | } |
| 387 | 367 | ||
| 388 | /* Locate a message digest content from a BIO chain based on SignerInfo */ | 368 | /* Locate a message digest content from a BIO chain based on SignerInfo */ |
| 389 | 369 | ||
| 390 | int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, | 370 | int |
| 391 | X509_ALGOR *mdalg) | 371 | cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg) |
| 392 | { | 372 | { |
| 393 | int nid; | 373 | int nid; |
| 394 | ASN1_OBJECT *mdoid; | 374 | ASN1_OBJECT *mdoid; |
| 375 | |||
| 395 | X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); | 376 | X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); |
| 396 | nid = OBJ_obj2nid(mdoid); | 377 | nid = OBJ_obj2nid(mdoid); |
| 378 | |||
| 397 | /* Look for digest type to match signature */ | 379 | /* Look for digest type to match signature */ |
| 398 | for (;;) | 380 | for (;;) { |
| 399 | { | ||
| 400 | EVP_MD_CTX *mtmp; | 381 | EVP_MD_CTX *mtmp; |
| 401 | chain = BIO_find_type(chain, BIO_TYPE_MD); | 382 | chain = BIO_find_type(chain, BIO_TYPE_MD); |
| 402 | if (chain == NULL) | 383 | if (chain == NULL) { |
| 403 | { | ||
| 404 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, | 384 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, |
| 405 | CMS_R_NO_MATCHING_DIGEST); | 385 | CMS_R_NO_MATCHING_DIGEST); |
| 406 | return 0; | 386 | return 0; |
| 407 | } | 387 | } |
| 408 | BIO_get_md_ctx(chain, &mtmp); | 388 | BIO_get_md_ctx(chain, &mtmp); |
| 409 | if (EVP_MD_CTX_type(mtmp) == nid | 389 | if (EVP_MD_CTX_type(mtmp) == nid |
| 410 | /* Workaround for broken implementations that use signature | 390 | /* Workaround for broken implementations that use signature |
| 411 | * algorithm OID instead of digest. | 391 | * algorithm OID instead of digest. |
| 412 | */ | 392 | */ || |
| 413 | || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) | 393 | EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) |
| 414 | return EVP_MD_CTX_copy_ex(mctx, mtmp); | 394 | return EVP_MD_CTX_copy_ex(mctx, mtmp); |
| 415 | chain = BIO_next(chain); | 395 | chain = BIO_next(chain); |
| 416 | } | ||
| 417 | } | 396 | } |
| 397 | } | ||
| 418 | 398 | ||
| 419 | static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms) | 399 | static STACK_OF(CMS_CertificateChoices) ** |
| 420 | { | 400 | cms_get0_certificate_choices(CMS_ContentInfo *cms) |
| 421 | switch (OBJ_obj2nid(cms->contentType)) | 401 | { |
| 422 | { | 402 | switch (OBJ_obj2nid(cms->contentType)) { |
| 423 | 403 | case NID_pkcs7_signed: | |
| 424 | case NID_pkcs7_signed: | ||
| 425 | return &cms->d.signedData->certificates; | 404 | return &cms->d.signedData->certificates; |
| 426 | 405 | case NID_pkcs7_enveloped: | |
| 427 | case NID_pkcs7_enveloped: | ||
| 428 | return &cms->d.envelopedData->originatorInfo->certificates; | 406 | return &cms->d.envelopedData->originatorInfo->certificates; |
| 429 | 407 | default: | |
| 430 | default: | ||
| 431 | CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, | 408 | CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, |
| 432 | CMS_R_UNSUPPORTED_CONTENT_TYPE); | 409 | CMS_R_UNSUPPORTED_CONTENT_TYPE); |
| 433 | return NULL; | 410 | return NULL; |
| 434 | |||
| 435 | } | ||
| 436 | } | 411 | } |
| 412 | } | ||
| 437 | 413 | ||
| 438 | CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) | 414 | CMS_CertificateChoices * |
| 439 | { | 415 | CMS_add0_CertificateChoices(CMS_ContentInfo *cms) |
| 416 | { | ||
| 440 | STACK_OF(CMS_CertificateChoices) **pcerts; | 417 | STACK_OF(CMS_CertificateChoices) **pcerts; |
| 441 | CMS_CertificateChoices *cch; | 418 | CMS_CertificateChoices *cch; |
| 419 | |||
| 442 | pcerts = cms_get0_certificate_choices(cms); | 420 | pcerts = cms_get0_certificate_choices(cms); |
| 443 | if (!pcerts) | 421 | if (!pcerts) |
| 444 | return NULL; | 422 | return NULL; |
| @@ -449,75 +427,73 @@ CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) | |||
| 449 | cch = M_ASN1_new_of(CMS_CertificateChoices); | 427 | cch = M_ASN1_new_of(CMS_CertificateChoices); |
| 450 | if (!cch) | 428 | if (!cch) |
| 451 | return NULL; | 429 | return NULL; |
| 452 | if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) | 430 | if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { |
| 453 | { | ||
| 454 | M_ASN1_free_of(cch, CMS_CertificateChoices); | 431 | M_ASN1_free_of(cch, CMS_CertificateChoices); |
| 455 | return NULL; | 432 | return NULL; |
| 456 | } | ||
| 457 | return cch; | ||
| 458 | } | 433 | } |
| 434 | return cch; | ||
| 435 | } | ||
| 459 | 436 | ||
| 460 | int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) | 437 | int |
| 461 | { | 438 | CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) |
| 439 | { | ||
| 462 | CMS_CertificateChoices *cch; | 440 | CMS_CertificateChoices *cch; |
| 463 | STACK_OF(CMS_CertificateChoices) **pcerts; | 441 | STACK_OF(CMS_CertificateChoices) **pcerts; |
| 464 | int i; | 442 | int i; |
| 443 | |||
| 465 | pcerts = cms_get0_certificate_choices(cms); | 444 | pcerts = cms_get0_certificate_choices(cms); |
| 466 | if (!pcerts) | 445 | if (!pcerts) |
| 467 | return 0; | 446 | return 0; |
| 468 | for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) | 447 | for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { |
| 469 | { | ||
| 470 | cch = sk_CMS_CertificateChoices_value(*pcerts, i); | 448 | cch = sk_CMS_CertificateChoices_value(*pcerts, i); |
| 471 | if (cch->type == CMS_CERTCHOICE_CERT) | 449 | if (cch->type == CMS_CERTCHOICE_CERT) { |
| 472 | { | 450 | if (!X509_cmp(cch->d.certificate, cert)) { |
| 473 | if (!X509_cmp(cch->d.certificate, cert)) | 451 | CMSerr(CMS_F_CMS_ADD0_CERT, |
| 474 | { | 452 | CMS_R_CERTIFICATE_ALREADY_PRESENT); |
| 475 | CMSerr(CMS_F_CMS_ADD0_CERT, | ||
| 476 | CMS_R_CERTIFICATE_ALREADY_PRESENT); | ||
| 477 | return 0; | 453 | return 0; |
| 478 | } | ||
| 479 | } | 454 | } |
| 480 | } | 455 | } |
| 456 | } | ||
| 481 | cch = CMS_add0_CertificateChoices(cms); | 457 | cch = CMS_add0_CertificateChoices(cms); |
| 482 | if (!cch) | 458 | if (!cch) |
| 483 | return 0; | 459 | return 0; |
| 484 | cch->type = CMS_CERTCHOICE_CERT; | 460 | cch->type = CMS_CERTCHOICE_CERT; |
| 485 | cch->d.certificate = cert; | 461 | cch->d.certificate = cert; |
| 486 | return 1; | 462 | return 1; |
| 487 | } | 463 | } |
| 488 | 464 | ||
| 489 | int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) | 465 | int |
| 490 | { | 466 | CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) |
| 467 | { | ||
| 491 | int r; | 468 | int r; |
| 469 | |||
| 492 | r = CMS_add0_cert(cms, cert); | 470 | r = CMS_add0_cert(cms, cert); |
| 493 | if (r > 0) | 471 | if (r > 0) |
| 494 | CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); | 472 | CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); |
| 495 | return r; | 473 | return r; |
| 496 | } | 474 | } |
| 497 | 475 | ||
| 498 | static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms) | 476 | static STACK_OF(CMS_RevocationInfoChoice) ** |
| 499 | { | 477 | cms_get0_revocation_choices(CMS_ContentInfo *cms) |
| 500 | switch (OBJ_obj2nid(cms->contentType)) | 478 | { |
| 501 | { | 479 | switch (OBJ_obj2nid(cms->contentType)) { |
| 502 | 480 | case NID_pkcs7_signed: | |
| 503 | case NID_pkcs7_signed: | ||
| 504 | return &cms->d.signedData->crls; | 481 | return &cms->d.signedData->crls; |
| 505 | 482 | case NID_pkcs7_enveloped: | |
| 506 | case NID_pkcs7_enveloped: | ||
| 507 | return &cms->d.envelopedData->originatorInfo->crls; | 483 | return &cms->d.envelopedData->originatorInfo->crls; |
| 508 | 484 | default: | |
| 509 | default: | ||
| 510 | CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, | 485 | CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, |
| 511 | CMS_R_UNSUPPORTED_CONTENT_TYPE); | 486 | CMS_R_UNSUPPORTED_CONTENT_TYPE); |
| 512 | return NULL; | 487 | return NULL; |
| 513 | |||
| 514 | } | ||
| 515 | } | 488 | } |
| 489 | } | ||
| 516 | 490 | ||
| 517 | CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) | 491 | CMS_RevocationInfoChoice * |
| 518 | { | 492 | CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) |
| 493 | { | ||
| 519 | STACK_OF(CMS_RevocationInfoChoice) **pcrls; | 494 | STACK_OF(CMS_RevocationInfoChoice) **pcrls; |
| 520 | CMS_RevocationInfoChoice *rch; | 495 | CMS_RevocationInfoChoice *rch; |
| 496 | |||
| 521 | pcrls = cms_get0_revocation_choices(cms); | 497 | pcrls = cms_get0_revocation_choices(cms); |
| 522 | if (!pcrls) | 498 | if (!pcrls) |
| 523 | return NULL; | 499 | return NULL; |
| @@ -528,95 +504,92 @@ CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) | |||
| 528 | rch = M_ASN1_new_of(CMS_RevocationInfoChoice); | 504 | rch = M_ASN1_new_of(CMS_RevocationInfoChoice); |
| 529 | if (!rch) | 505 | if (!rch) |
| 530 | return NULL; | 506 | return NULL; |
| 531 | if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) | 507 | if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { |
| 532 | { | ||
| 533 | M_ASN1_free_of(rch, CMS_RevocationInfoChoice); | 508 | M_ASN1_free_of(rch, CMS_RevocationInfoChoice); |
| 534 | return NULL; | 509 | return NULL; |
| 535 | } | ||
| 536 | return rch; | ||
| 537 | } | 510 | } |
| 511 | return rch; | ||
| 512 | } | ||
| 538 | 513 | ||
| 539 | int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) | 514 | int |
| 540 | { | 515 | CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) |
| 516 | { | ||
| 541 | CMS_RevocationInfoChoice *rch; | 517 | CMS_RevocationInfoChoice *rch; |
| 518 | |||
| 542 | rch = CMS_add0_RevocationInfoChoice(cms); | 519 | rch = CMS_add0_RevocationInfoChoice(cms); |
| 543 | if (!rch) | 520 | if (!rch) |
| 544 | return 0; | 521 | return 0; |
| 545 | rch->type = CMS_REVCHOICE_CRL; | 522 | rch->type = CMS_REVCHOICE_CRL; |
| 546 | rch->d.crl = crl; | 523 | rch->d.crl = crl; |
| 547 | return 1; | 524 | return 1; |
| 548 | } | 525 | } |
| 549 | 526 | ||
| 550 | int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) | 527 | int |
| 551 | { | 528 | CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) |
| 529 | { | ||
| 552 | int r; | 530 | int r; |
| 531 | |||
| 553 | r = CMS_add0_crl(cms, crl); | 532 | r = CMS_add0_crl(cms, crl); |
| 554 | if (r > 0) | 533 | if (r > 0) |
| 555 | CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); | 534 | CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); |
| 556 | return r; | 535 | return r; |
| 557 | } | 536 | } |
| 558 | 537 | ||
| 559 | STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) | 538 | STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) |
| 560 | { | 539 | { |
| 561 | STACK_OF(X509) *certs = NULL; | 540 | STACK_OF(X509) *certs = NULL; |
| 562 | CMS_CertificateChoices *cch; | 541 | CMS_CertificateChoices *cch; |
| 563 | STACK_OF(CMS_CertificateChoices) **pcerts; | 542 | STACK_OF(CMS_CertificateChoices) **pcerts; |
| 564 | int i; | 543 | int i; |
| 544 | |||
| 565 | pcerts = cms_get0_certificate_choices(cms); | 545 | pcerts = cms_get0_certificate_choices(cms); |
| 566 | if (!pcerts) | 546 | if (!pcerts) |
| 567 | return NULL; | 547 | return NULL; |
| 568 | for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) | 548 | for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { |
| 569 | { | ||
| 570 | cch = sk_CMS_CertificateChoices_value(*pcerts, i); | 549 | cch = sk_CMS_CertificateChoices_value(*pcerts, i); |
| 571 | if (cch->type == 0) | 550 | if (cch->type == 0) { |
| 572 | { | 551 | if (!certs) { |
| 573 | if (!certs) | ||
| 574 | { | ||
| 575 | certs = sk_X509_new_null(); | 552 | certs = sk_X509_new_null(); |
| 576 | if (!certs) | 553 | if (!certs) |
| 577 | return NULL; | 554 | return NULL; |
| 578 | } | 555 | } |
| 579 | if (!sk_X509_push(certs, cch->d.certificate)) | 556 | if (!sk_X509_push(certs, cch->d.certificate)) { |
| 580 | { | ||
| 581 | sk_X509_pop_free(certs, X509_free); | 557 | sk_X509_pop_free(certs, X509_free); |
| 582 | return NULL; | 558 | return NULL; |
| 583 | } | ||
| 584 | CRYPTO_add(&cch->d.certificate->references, | ||
| 585 | 1, CRYPTO_LOCK_X509); | ||
| 586 | } | 559 | } |
| 560 | CRYPTO_add(&cch->d.certificate->references, | ||
| 561 | 1, CRYPTO_LOCK_X509); | ||
| 587 | } | 562 | } |
| 563 | } | ||
| 588 | return certs; | 564 | return certs; |
| 589 | 565 | ||
| 590 | } | 566 | } |
| 591 | 567 | ||
| 592 | STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) | 568 | STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) |
| 593 | { | 569 | { |
| 594 | STACK_OF(X509_CRL) *crls = NULL; | 570 | STACK_OF(X509_CRL) *crls = NULL; |
| 595 | STACK_OF(CMS_RevocationInfoChoice) **pcrls; | 571 | STACK_OF(CMS_RevocationInfoChoice) **pcrls; |
| 596 | CMS_RevocationInfoChoice *rch; | 572 | CMS_RevocationInfoChoice *rch; |
| 597 | int i; | 573 | int i; |
| 574 | |||
| 598 | pcrls = cms_get0_revocation_choices(cms); | 575 | pcrls = cms_get0_revocation_choices(cms); |
| 599 | if (!pcrls) | 576 | if (!pcrls) |
| 600 | return NULL; | 577 | return NULL; |
| 601 | for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) | 578 | for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { |
| 602 | { | ||
| 603 | rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); | 579 | rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); |
| 604 | if (rch->type == 0) | 580 | if (rch->type == 0) { |
| 605 | { | 581 | if (!crls) { |
| 606 | if (!crls) | ||
| 607 | { | ||
| 608 | crls = sk_X509_CRL_new_null(); | 582 | crls = sk_X509_CRL_new_null(); |
| 609 | if (!crls) | 583 | if (!crls) |
| 610 | return NULL; | 584 | return NULL; |
| 611 | } | 585 | } |
| 612 | if (!sk_X509_CRL_push(crls, rch->d.crl)) | 586 | if (!sk_X509_CRL_push(crls, rch->d.crl)) { |
| 613 | { | ||
| 614 | sk_X509_CRL_pop_free(crls, X509_CRL_free); | 587 | sk_X509_CRL_pop_free(crls, X509_CRL_free); |
| 615 | return NULL; | 588 | return NULL; |
| 616 | } | ||
| 617 | CRYPTO_add(&rch->d.crl->references, | ||
| 618 | 1, CRYPTO_LOCK_X509_CRL); | ||
| 619 | } | 589 | } |
| 590 | CRYPTO_add(&rch->d.crl->references, | ||
| 591 | 1, CRYPTO_LOCK_X509_CRL); | ||
| 620 | } | 592 | } |
| 621 | return crls; | ||
| 622 | } | 593 | } |
| 594 | return crls; | ||
| 595 | } | ||
