Rich Salz | 6286757 | 2016-05-17 14:24:46 -0400 | [diff] [blame] | 1 | /* |
Matt Caswell | fecb3aa | 2022-05-03 11:52:38 +0100 | [diff] [blame] | 2 | * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 3 | * |
Richard Levitte | b7617a3 | 2018-12-06 13:50:13 +0100 | [diff] [blame] | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
Rich Salz | 6286757 | 2016-05-17 14:24:46 -0400 | [diff] [blame] | 5 | * this file except in compliance with the License. You can obtain a copy |
| 6 | * in the file LICENSE in the source distribution or at |
| 7 | * https://www.openssl.org/source/license.html |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 8 | */ |
| 9 | |
| 10 | #include <stdio.h> |
Richard Levitte | b39fc56 | 2015-05-14 16:56:48 +0200 | [diff] [blame] | 11 | #include "internal/cryptlib.h" |
Bodo Möller | ec57782 | 1999-04-23 22:13:45 +0000 | [diff] [blame] | 12 | #include <openssl/objects.h> |
| 13 | #include <openssl/x509.h> |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 14 | #include <openssl/pkcs7.h> |
Dr. Matthias St. Pierre | 25f2138 | 2019-09-28 00:45:33 +0200 | [diff] [blame] | 15 | #include "crypto/asn1.h" |
| 16 | #include "crypto/evp.h" |
Dr. David von Oheimb | eeccc23 | 2020-04-26 18:30:45 +0200 | [diff] [blame] | 17 | #include "crypto/x509.h" /* for sk_X509_add1_cert() */ |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 18 | #include "pk7_local.h" |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 19 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 20 | long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 21 | { |
| 22 | int nid; |
| 23 | long ret; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 24 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 25 | nid = OBJ_obj2nid(p7->type); |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 26 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 27 | switch (cmd) { |
Emilia Kasper | c225c3c | 2015-02-27 16:52:23 +0100 | [diff] [blame] | 28 | /* NOTE(emilia): does not support detached digested data. */ |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 29 | case PKCS7_OP_SET_DETACHED_SIGNATURE: |
| 30 | if (nid == NID_pkcs7_signed) { |
| 31 | ret = p7->detached = (int)larg; |
| 32 | if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { |
| 33 | ASN1_OCTET_STRING *os; |
| 34 | os = p7->d.sign->contents->d.data; |
| 35 | ASN1_OCTET_STRING_free(os); |
| 36 | p7->d.sign->contents->d.data = NULL; |
| 37 | } |
| 38 | } else { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 39 | ERR_raise(ERR_LIB_PKCS7, |
| 40 | PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 41 | ret = 0; |
| 42 | } |
| 43 | break; |
| 44 | case PKCS7_OP_GET_DETACHED_SIGNATURE: |
| 45 | if (nid == NID_pkcs7_signed) { |
Rich Salz | 12a765a | 2019-09-16 15:28:57 -0400 | [diff] [blame] | 46 | if (p7->d.sign == NULL || p7->d.sign->contents->d.ptr == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 47 | ret = 1; |
| 48 | else |
| 49 | ret = 0; |
| 50 | |
| 51 | p7->detached = ret; |
| 52 | } else { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 53 | ERR_raise(ERR_LIB_PKCS7, |
| 54 | PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 55 | ret = 0; |
| 56 | } |
| 57 | |
| 58 | break; |
| 59 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 60 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 61 | ret = 0; |
| 62 | } |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 63 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 64 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 65 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 66 | int PKCS7_content_new(PKCS7 *p7, int type) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 67 | { |
| 68 | PKCS7 *ret = NULL; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 69 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 70 | if ((ret = PKCS7_new()) == NULL) |
| 71 | goto err; |
| 72 | if (!PKCS7_set_type(ret, type)) |
| 73 | goto err; |
| 74 | if (!PKCS7_set_content(p7, ret)) |
| 75 | goto err; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 76 | |
KaoruToda | 208fb89 | 2017-10-09 20:05:58 +0900 | [diff] [blame] | 77 | return 1; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 78 | err: |
Rich Salz | e0e920b | 2015-04-11 16:32:54 -0400 | [diff] [blame] | 79 | PKCS7_free(ret); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 80 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 81 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 82 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 83 | int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 84 | { |
| 85 | int i; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 86 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 87 | i = OBJ_obj2nid(p7->type); |
| 88 | switch (i) { |
| 89 | case NID_pkcs7_signed: |
Rich Salz | e0e920b | 2015-04-11 16:32:54 -0400 | [diff] [blame] | 90 | PKCS7_free(p7->d.sign->contents); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 91 | p7->d.sign->contents = p7_data; |
| 92 | break; |
| 93 | case NID_pkcs7_digest: |
Rich Salz | e0e920b | 2015-04-11 16:32:54 -0400 | [diff] [blame] | 94 | PKCS7_free(p7->d.digest->contents); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 95 | p7->d.digest->contents = p7_data; |
| 96 | break; |
| 97 | case NID_pkcs7_data: |
| 98 | case NID_pkcs7_enveloped: |
| 99 | case NID_pkcs7_signedAndEnveloped: |
| 100 | case NID_pkcs7_encrypted: |
| 101 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 102 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 103 | goto err; |
| 104 | } |
KaoruToda | 208fb89 | 2017-10-09 20:05:58 +0900 | [diff] [blame] | 105 | return 1; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 106 | err: |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 107 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 108 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 109 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 110 | int PKCS7_set_type(PKCS7 *p7, int type) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 111 | { |
| 112 | ASN1_OBJECT *obj; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 113 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 114 | /* |
| 115 | * PKCS7_content_free(p7); |
| 116 | */ |
| 117 | obj = OBJ_nid2obj(type); /* will not fail */ |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 118 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 119 | switch (type) { |
| 120 | case NID_pkcs7_signed: |
| 121 | p7->type = obj; |
| 122 | if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) |
| 123 | goto err; |
| 124 | if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { |
| 125 | PKCS7_SIGNED_free(p7->d.sign); |
| 126 | p7->d.sign = NULL; |
| 127 | goto err; |
| 128 | } |
| 129 | break; |
| 130 | case NID_pkcs7_data: |
| 131 | p7->type = obj; |
Dr. Stephen Henson | f422a51 | 2015-03-14 04:16:42 +0000 | [diff] [blame] | 132 | if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 133 | goto err; |
| 134 | break; |
| 135 | case NID_pkcs7_signedAndEnveloped: |
| 136 | p7->type = obj; |
| 137 | if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new()) |
| 138 | == NULL) |
| 139 | goto err; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 140 | if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) |
| 141 | goto err; |
| 142 | p7->d.signed_and_enveloped->enc_data->content_type |
| 143 | = OBJ_nid2obj(NID_pkcs7_data); |
| 144 | break; |
| 145 | case NID_pkcs7_enveloped: |
| 146 | p7->type = obj; |
| 147 | if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) |
| 148 | == NULL) |
| 149 | goto err; |
| 150 | if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) |
| 151 | goto err; |
| 152 | p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); |
| 153 | break; |
| 154 | case NID_pkcs7_encrypted: |
| 155 | p7->type = obj; |
| 156 | if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) |
| 157 | == NULL) |
| 158 | goto err; |
| 159 | if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) |
| 160 | goto err; |
| 161 | p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); |
| 162 | break; |
Dr. Stephen Henson | c6c3450 | 1999-08-17 12:58:01 +0000 | [diff] [blame] | 163 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 164 | case NID_pkcs7_digest: |
| 165 | p7->type = obj; |
| 166 | if ((p7->d.digest = PKCS7_DIGEST_new()) |
| 167 | == NULL) |
| 168 | goto err; |
| 169 | if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) |
| 170 | goto err; |
| 171 | break; |
| 172 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 173 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 174 | goto err; |
| 175 | } |
KaoruToda | 208fb89 | 2017-10-09 20:05:58 +0900 | [diff] [blame] | 176 | return 1; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 177 | err: |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 178 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 179 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 180 | |
Dr. Stephen Henson | 8d9086d | 2003-10-10 23:40:47 +0000 | [diff] [blame] | 181 | int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 182 | { |
| 183 | p7->type = OBJ_nid2obj(type); |
| 184 | p7->d.other = other; |
| 185 | return 1; |
| 186 | } |
Dr. Stephen Henson | 8d9086d | 2003-10-10 23:40:47 +0000 | [diff] [blame] | 187 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 188 | int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 189 | { |
Richard Levitte | ad57a13 | 2021-03-10 12:58:53 +0100 | [diff] [blame] | 190 | int i, j; |
| 191 | ASN1_OBJECT *obj; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 192 | X509_ALGOR *alg; |
| 193 | STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; |
| 194 | STACK_OF(X509_ALGOR) *md_sk; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 195 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 196 | i = OBJ_obj2nid(p7->type); |
| 197 | switch (i) { |
| 198 | case NID_pkcs7_signed: |
| 199 | signer_sk = p7->d.sign->signer_info; |
| 200 | md_sk = p7->d.sign->md_algs; |
| 201 | break; |
| 202 | case NID_pkcs7_signedAndEnveloped: |
| 203 | signer_sk = p7->d.signed_and_enveloped->signer_info; |
| 204 | md_sk = p7->d.signed_and_enveloped->md_algs; |
| 205 | break; |
| 206 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 207 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 208 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 209 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 210 | |
Richard Levitte | ad57a13 | 2021-03-10 12:58:53 +0100 | [diff] [blame] | 211 | obj = psi->digest_alg->algorithm; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 212 | /* If the digest is not currently listed, add it */ |
| 213 | j = 0; |
| 214 | for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { |
| 215 | alg = sk_X509_ALGOR_value(md_sk, i); |
Richard Levitte | ad57a13 | 2021-03-10 12:58:53 +0100 | [diff] [blame] | 216 | if (OBJ_cmp(obj, alg->algorithm) == 0) { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 217 | j = 1; |
| 218 | break; |
| 219 | } |
| 220 | } |
| 221 | if (!j) { /* we need to add another algorithm */ |
Richard Levitte | ad57a13 | 2021-03-10 12:58:53 +0100 | [diff] [blame] | 222 | int nid; |
| 223 | |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 224 | if ((alg = X509_ALGOR_new()) == NULL |
| 225 | || (alg->parameter = ASN1_TYPE_new()) == NULL) { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 226 | X509_ALGOR_free(alg); |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 227 | ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 228 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 229 | } |
Richard Levitte | ad57a13 | 2021-03-10 12:58:53 +0100 | [diff] [blame] | 230 | /* |
| 231 | * If there is a constant copy of the ASN1 OBJECT in libcrypto, then |
| 232 | * use that. Otherwise, use a dynamically duplicated copy |
| 233 | */ |
| 234 | if ((nid = OBJ_obj2nid(obj)) != NID_undef) |
| 235 | alg->algorithm = OBJ_nid2obj(nid); |
| 236 | else |
| 237 | alg->algorithm = OBJ_dup(obj); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 238 | alg->parameter->type = V_ASN1_NULL; |
Richard Levitte | ad57a13 | 2021-03-10 12:58:53 +0100 | [diff] [blame] | 239 | if (alg->algorithm == NULL || !sk_X509_ALGOR_push(md_sk, alg)) { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 240 | X509_ALGOR_free(alg); |
| 241 | return 0; |
| 242 | } |
| 243 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 244 | |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 245 | psi->ctx = ossl_pkcs7_get0_ctx(p7); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 246 | if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) |
| 247 | return 0; |
KaoruToda | 208fb89 | 2017-10-09 20:05:58 +0900 | [diff] [blame] | 248 | return 1; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 249 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 250 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 251 | int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 252 | { |
| 253 | int i; |
| 254 | STACK_OF(X509) **sk; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 255 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 256 | i = OBJ_obj2nid(p7->type); |
| 257 | switch (i) { |
| 258 | case NID_pkcs7_signed: |
| 259 | sk = &(p7->d.sign->cert); |
| 260 | break; |
| 261 | case NID_pkcs7_signedAndEnveloped: |
| 262 | sk = &(p7->d.signed_and_enveloped->cert); |
| 263 | break; |
| 264 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 265 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 266 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 267 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 268 | |
Dr. David von Oheimb | c1be4d6 | 2021-02-17 12:29:39 +0100 | [diff] [blame] | 269 | return ossl_x509_add_cert_new(sk, x509, X509_ADD_FLAG_UP_REF); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 270 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 271 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 272 | int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 273 | { |
| 274 | int i; |
| 275 | STACK_OF(X509_CRL) **sk; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 276 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 277 | i = OBJ_obj2nid(p7->type); |
| 278 | switch (i) { |
| 279 | case NID_pkcs7_signed: |
| 280 | sk = &(p7->d.sign->crl); |
| 281 | break; |
| 282 | case NID_pkcs7_signedAndEnveloped: |
| 283 | sk = &(p7->d.signed_and_enveloped->crl); |
| 284 | break; |
| 285 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 286 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 287 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 288 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 289 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 290 | if (*sk == NULL) |
| 291 | *sk = sk_X509_CRL_new_null(); |
| 292 | if (*sk == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 293 | ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 294 | return 0; |
| 295 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 296 | |
Dr. Stephen Henson | 65cbf98 | 2015-08-31 20:30:20 +0100 | [diff] [blame] | 297 | X509_CRL_up_ref(crl); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 298 | if (!sk_X509_CRL_push(*sk, crl)) { |
| 299 | X509_CRL_free(crl); |
| 300 | return 0; |
| 301 | } |
KaoruToda | 208fb89 | 2017-10-09 20:05:58 +0900 | [diff] [blame] | 302 | return 1; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 303 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 304 | |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 305 | static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, |
| 306 | int verify) |
| 307 | { |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 308 | if (!verify) { |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 309 | int snid, hnid; |
| 310 | X509_ALGOR *alg1, *alg2; |
| 311 | EVP_PKEY *pkey = si->pkey; |
| 312 | |
| 313 | PKCS7_SIGNER_INFO_get0_algs(si, NULL, &alg1, &alg2); |
| 314 | if (alg1 == NULL || alg1->algorithm == NULL) |
| 315 | return -1; |
| 316 | hnid = OBJ_obj2nid(alg1->algorithm); |
| 317 | if (hnid == NID_undef) |
| 318 | return -1; |
Tomas Mraz | ed576ac | 2021-05-21 16:58:08 +0200 | [diff] [blame] | 319 | if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_get_id(pkey))) |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 320 | return -1; |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 321 | return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL); |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 322 | } |
| 323 | return 1; |
| 324 | } |
| 325 | |
| 326 | static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify) |
| 327 | { |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 328 | if (!verify) { |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 329 | X509_ALGOR *alg = NULL; |
| 330 | |
| 331 | PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg); |
| 332 | if (alg != NULL) |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 333 | return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), |
| 334 | V_ASN1_NULL, NULL); |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 335 | } |
| 336 | return 1; |
| 337 | } |
| 338 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 339 | int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 340 | const EVP_MD *dgst) |
| 341 | { |
| 342 | int ret; |
Bodo Möller | 279fe3b | 2002-05-07 15:14:12 +0000 | [diff] [blame] | 343 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 344 | /* We now need to add another PKCS7_SIGNER_INFO entry */ |
| 345 | if (!ASN1_INTEGER_set(p7i->version, 1)) |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 346 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 347 | if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, |
| 348 | X509_get_issuer_name(x509))) |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 349 | return 0; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 350 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 351 | /* |
| 352 | * because ASN1_INTEGER_set is used to set a 'long' we will do things the |
| 353 | * ugly way. |
| 354 | */ |
Dr. Stephen Henson | f422a51 | 2015-03-14 04:16:42 +0000 | [diff] [blame] | 355 | ASN1_INTEGER_free(p7i->issuer_and_serial->serial); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 356 | if (!(p7i->issuer_and_serial->serial = |
Dr. David von Oheimb | 1337a3a | 2020-07-13 17:13:48 +0200 | [diff] [blame] | 357 | ASN1_INTEGER_dup(X509_get0_serialNumber(x509)))) |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 358 | return 0; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 359 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 360 | /* lets keep the pkey around for a while */ |
Dr. Stephen Henson | 3aeb934 | 2016-01-19 00:21:12 +0000 | [diff] [blame] | 361 | EVP_PKEY_up_ref(pkey); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 362 | p7i->pkey = pkey; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 363 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 364 | /* Set the algorithms */ |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 365 | |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 366 | if (!X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_get_type(dgst)), |
| 367 | V_ASN1_NULL, NULL)) |
| 368 | return 0; |
Dr. Stephen Henson | 10243d9 | 1999-05-11 00:52:46 +0000 | [diff] [blame] | 369 | |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 370 | if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "DSA")) |
| 371 | return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i, 0); |
| 372 | if (EVP_PKEY_is_a(pkey, "RSA")) |
| 373 | return pkcs7_rsa_sign_verify_setup(p7i, 0); |
| 374 | |
| 375 | if (pkey->ameth != NULL && pkey->ameth->pkey_ctrl != NULL) { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 376 | ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i); |
| 377 | if (ret > 0) |
| 378 | return 1; |
| 379 | if (ret != -2) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 380 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 381 | return 0; |
| 382 | } |
| 383 | } |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 384 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 385 | return 0; |
| 386 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 387 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 388 | PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 389 | const EVP_MD *dgst) |
| 390 | { |
| 391 | PKCS7_SIGNER_INFO *si = NULL; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 392 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 393 | if (dgst == NULL) { |
| 394 | int def_nid; |
| 395 | if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) |
| 396 | goto err; |
| 397 | dgst = EVP_get_digestbynid(def_nid); |
| 398 | if (dgst == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 399 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 400 | goto err; |
| 401 | } |
| 402 | } |
Dr. Stephen Henson | 3d47929 | 2006-05-07 17:22:58 +0000 | [diff] [blame] | 403 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 404 | if ((si = PKCS7_SIGNER_INFO_new()) == NULL) |
| 405 | goto err; |
| 406 | if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) |
| 407 | goto err; |
| 408 | if (!PKCS7_add_signer(p7, si)) |
| 409 | goto err; |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 410 | return si; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 411 | err: |
Rich Salz | e0e920b | 2015-04-11 16:32:54 -0400 | [diff] [blame] | 412 | PKCS7_SIGNER_INFO_free(si); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 413 | return NULL; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 414 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 415 | |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 416 | static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7) |
| 417 | { |
| 418 | if (PKCS7_type_is_signed(p7)) |
| 419 | return p7->d.sign->cert; |
| 420 | if (PKCS7_type_is_signedAndEnveloped(p7)) |
| 421 | return p7->d.signed_and_enveloped->cert; |
| 422 | return NULL; |
| 423 | } |
| 424 | |
| 425 | static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7) |
| 426 | { |
| 427 | if (PKCS7_type_is_signedAndEnveloped(p7)) |
| 428 | return p7->d.signed_and_enveloped->recipientinfo; |
| 429 | if (PKCS7_type_is_enveloped(p7)) |
| 430 | return p7->d.enveloped->recipientinfo; |
| 431 | return NULL; |
| 432 | } |
| 433 | |
| 434 | /* |
| 435 | * Set up the library context into any loaded structure that needs it. |
| 436 | * i.e loaded X509 objects. |
| 437 | */ |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 438 | void ossl_pkcs7_resolve_libctx(PKCS7 *p7) |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 439 | { |
| 440 | int i; |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 441 | const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7); |
| 442 | OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx); |
| 443 | const char *propq = ossl_pkcs7_ctx_get0_propq(ctx); |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 444 | STACK_OF(PKCS7_RECIP_INFO) *rinfos = pkcs7_get_recipient_info(p7); |
| 445 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7); |
| 446 | STACK_OF(X509) *certs = pkcs7_get_signer_certs(p7); |
| 447 | |
| 448 | if (ctx == NULL) |
| 449 | return; |
| 450 | |
| 451 | for (i = 0; i < sk_X509_num(certs); i++) |
Shane Lontis | 4669015 | 2021-03-09 14:18:03 +1000 | [diff] [blame] | 452 | ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq); |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 453 | |
| 454 | for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) { |
| 455 | PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i); |
| 456 | |
Shane Lontis | 4669015 | 2021-03-09 14:18:03 +1000 | [diff] [blame] | 457 | ossl_x509_set0_libctx(ri->cert, libctx, propq); |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 458 | } |
| 459 | |
| 460 | for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { |
| 461 | PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); |
| 462 | |
| 463 | if (si != NULL) |
| 464 | si->ctx = ctx; |
| 465 | } |
| 466 | } |
| 467 | |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 468 | const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7) |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 469 | { |
| 470 | return p7 != NULL ? &p7->ctx : NULL; |
| 471 | } |
| 472 | |
Jon Spillett | b536880 | 2021-02-17 17:56:36 +1000 | [diff] [blame] | 473 | void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx) |
| 474 | { |
| 475 | p7->ctx.libctx = ctx; |
| 476 | } |
| 477 | |
| 478 | int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq) |
| 479 | { |
| 480 | if (p7->ctx.propq != NULL) { |
| 481 | OPENSSL_free(p7->ctx.propq); |
| 482 | p7->ctx.propq = NULL; |
| 483 | } |
| 484 | if (propq != NULL) { |
| 485 | p7->ctx.propq = OPENSSL_strdup(propq); |
| 486 | if (p7->ctx.propq == NULL) { |
| 487 | ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); |
| 488 | return 0; |
| 489 | } |
| 490 | } |
| 491 | return 1; |
| 492 | } |
| 493 | |
| 494 | int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to) |
| 495 | { |
| 496 | ossl_pkcs7_set0_libctx(to, from->ctx.libctx); |
| 497 | if (!ossl_pkcs7_set1_propq(to, from->ctx.propq)) |
| 498 | return 0; |
| 499 | |
| 500 | ossl_pkcs7_resolve_libctx(to); |
| 501 | return 1; |
| 502 | } |
| 503 | |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 504 | OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx) |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 505 | { |
| 506 | return ctx != NULL ? ctx->libctx : NULL; |
| 507 | } |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 508 | const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx) |
Shane Lontis | 90a1f2d | 2020-07-25 19:11:03 +1000 | [diff] [blame] | 509 | { |
| 510 | return ctx != NULL ? ctx->propq : NULL; |
| 511 | } |
| 512 | |
Dr. Stephen Henson | c5a5546 | 2003-10-11 22:11:45 +0000 | [diff] [blame] | 513 | int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 514 | { |
| 515 | if (PKCS7_type_is_digest(p7)) { |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 516 | if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 517 | ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 518 | return 0; |
| 519 | } |
| 520 | p7->d.digest->md->parameter->type = V_ASN1_NULL; |
| 521 | p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); |
| 522 | return 1; |
| 523 | } |
| 524 | |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 525 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 526 | return 1; |
| 527 | } |
Dr. Stephen Henson | c5a5546 | 2003-10-11 22:11:45 +0000 | [diff] [blame] | 528 | |
Ben Laurie | b05b50e | 1999-06-02 17:11:53 +0000 | [diff] [blame] | 529 | STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 530 | { |
Emilia Kasper | c225c3c | 2015-02-27 16:52:23 +0100 | [diff] [blame] | 531 | if (p7 == NULL || p7->d.ptr == NULL) |
| 532 | return NULL; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 533 | if (PKCS7_type_is_signed(p7)) { |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 534 | return p7->d.sign->signer_info; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 535 | } else if (PKCS7_type_is_signedAndEnveloped(p7)) { |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 536 | return p7->d.signed_and_enveloped->signer_info; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 537 | } else |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 538 | return NULL; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 539 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 540 | |
Dr. Stephen Henson | 492a9e2 | 2006-04-17 17:12:23 +0000 | [diff] [blame] | 541 | void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 542 | X509_ALGOR **pdig, X509_ALGOR **psig) |
| 543 | { |
| 544 | if (pk) |
| 545 | *pk = si->pkey; |
| 546 | if (pdig) |
| 547 | *pdig = si->digest_alg; |
| 548 | if (psig) |
| 549 | *psig = si->digest_enc_alg; |
| 550 | } |
Dr. Stephen Henson | 492a9e2 | 2006-04-17 17:12:23 +0000 | [diff] [blame] | 551 | |
Dr. Stephen Henson | e4b21c7 | 2006-04-27 00:29:50 +0000 | [diff] [blame] | 552 | void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 553 | { |
| 554 | if (penc) |
| 555 | *penc = ri->key_enc_algor; |
| 556 | } |
Dr. Stephen Henson | e4b21c7 | 2006-04-27 00:29:50 +0000 | [diff] [blame] | 557 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 558 | PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 559 | { |
| 560 | PKCS7_RECIP_INFO *ri; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 561 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 562 | if ((ri = PKCS7_RECIP_INFO_new()) == NULL) |
| 563 | goto err; |
| 564 | if (!PKCS7_RECIP_INFO_set(ri, x509)) |
| 565 | goto err; |
| 566 | if (!PKCS7_add_recipient_info(p7, ri)) |
| 567 | goto err; |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 568 | ri->ctx = ossl_pkcs7_get0_ctx(p7); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 569 | return ri; |
| 570 | err: |
Rich Salz | e0e920b | 2015-04-11 16:32:54 -0400 | [diff] [blame] | 571 | PKCS7_RECIP_INFO_free(ri); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 572 | return NULL; |
| 573 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 574 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 575 | int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 576 | { |
| 577 | int i; |
| 578 | STACK_OF(PKCS7_RECIP_INFO) *sk; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 579 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 580 | i = OBJ_obj2nid(p7->type); |
| 581 | switch (i) { |
| 582 | case NID_pkcs7_signedAndEnveloped: |
| 583 | sk = p7->d.signed_and_enveloped->recipientinfo; |
| 584 | break; |
| 585 | case NID_pkcs7_enveloped: |
| 586 | sk = p7->d.enveloped->recipientinfo; |
| 587 | break; |
| 588 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 589 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 590 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 591 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 592 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 593 | if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) |
| 594 | return 0; |
KaoruToda | 208fb89 | 2017-10-09 20:05:58 +0900 | [diff] [blame] | 595 | return 1; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 596 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 597 | |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 598 | static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt) |
| 599 | { |
| 600 | X509_ALGOR *alg = NULL; |
| 601 | |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 602 | if (!decrypt) { |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 603 | PKCS7_RECIP_INFO_get0_alg(ri, &alg); |
| 604 | if (alg != NULL) |
Dr. David von Oheimb | 04bc3c1 | 2021-08-06 12:11:13 +0200 | [diff] [blame] | 605 | return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), |
| 606 | V_ASN1_NULL, NULL); |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 607 | } |
| 608 | return 1; |
| 609 | } |
| 610 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 611 | int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 612 | { |
| 613 | int ret; |
| 614 | EVP_PKEY *pkey = NULL; |
| 615 | if (!ASN1_INTEGER_set(p7i->version, 0)) |
| 616 | return 0; |
| 617 | if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, |
| 618 | X509_get_issuer_name(x509))) |
| 619 | return 0; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 620 | |
Dr. Stephen Henson | f422a51 | 2015-03-14 04:16:42 +0000 | [diff] [blame] | 621 | ASN1_INTEGER_free(p7i->issuer_and_serial->serial); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 622 | if (!(p7i->issuer_and_serial->serial = |
Dr. David von Oheimb | 1337a3a | 2020-07-13 17:13:48 +0200 | [diff] [blame] | 623 | ASN1_INTEGER_dup(X509_get0_serialNumber(x509)))) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 624 | return 0; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 625 | |
Dr. Stephen Henson | 8382fd3 | 2015-12-20 00:32:36 +0000 | [diff] [blame] | 626 | pkey = X509_get0_pubkey(x509); |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 627 | if (pkey == NULL) |
| 628 | return 0; |
Dr. Stephen Henson | a78568b | 2006-04-27 18:20:34 +0000 | [diff] [blame] | 629 | |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 630 | if (EVP_PKEY_is_a(pkey, "RSA-PSS")) |
| 631 | return -2; |
| 632 | if (EVP_PKEY_is_a(pkey, "RSA")) { |
| 633 | if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0) |
| 634 | goto err; |
| 635 | goto finished; |
| 636 | } |
| 637 | |
| 638 | if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 639 | ERR_raise(ERR_LIB_PKCS7, |
| 640 | PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 641 | goto err; |
| 642 | } |
Dr. Stephen Henson | a78568b | 2006-04-27 18:20:34 +0000 | [diff] [blame] | 643 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 644 | ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i); |
| 645 | if (ret == -2) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 646 | ERR_raise(ERR_LIB_PKCS7, |
| 647 | PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 648 | goto err; |
| 649 | } |
| 650 | if (ret <= 0) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 651 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 652 | goto err; |
| 653 | } |
Shane Lontis | 3e878d9 | 2020-11-18 16:56:29 +1000 | [diff] [blame] | 654 | finished: |
Dr. Stephen Henson | 05f0fb9 | 2015-08-31 20:29:57 +0100 | [diff] [blame] | 655 | X509_up_ref(x509); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 656 | p7i->cert = x509; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 657 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 658 | return 1; |
Dr. Stephen Henson | a78568b | 2006-04-27 18:20:34 +0000 | [diff] [blame] | 659 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 660 | err: |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 661 | return 0; |
| 662 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 663 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 664 | X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 665 | { |
| 666 | if (PKCS7_type_is_signed(p7)) |
| 667 | return (X509_find_by_issuer_and_serial(p7->d.sign->cert, |
| 668 | si->issuer_and_serial->issuer, |
| 669 | si-> |
| 670 | issuer_and_serial->serial)); |
| 671 | else |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 672 | return NULL; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 673 | } |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 674 | |
Dr. Stephen Henson | 84fa704 | 1999-05-16 00:25:36 +0000 | [diff] [blame] | 675 | int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 676 | { |
| 677 | int i; |
| 678 | PKCS7_ENC_CONTENT *ec; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 679 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 680 | i = OBJ_obj2nid(p7->type); |
| 681 | switch (i) { |
| 682 | case NID_pkcs7_signedAndEnveloped: |
| 683 | ec = p7->d.signed_and_enveloped->enc_data; |
| 684 | break; |
| 685 | case NID_pkcs7_enveloped: |
| 686 | ec = p7->d.enveloped->enc_data; |
| 687 | break; |
| 688 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 689 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 690 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 691 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 692 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 693 | /* Check cipher OID exists and has data in it */ |
Tomas Mraz | ed576ac | 2021-05-21 16:58:08 +0200 | [diff] [blame] | 694 | i = EVP_CIPHER_get_type(cipher); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 695 | if (i == NID_undef) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 696 | ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 697 | return 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 698 | } |
Dr. Stephen Henson | 84fa704 | 1999-05-16 00:25:36 +0000 | [diff] [blame] | 699 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 700 | ec->cipher = cipher; |
Shane Lontis | 681618c | 2021-02-19 17:29:29 +1000 | [diff] [blame] | 701 | ec->ctx = ossl_pkcs7_get0_ctx(p7); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 702 | return 1; |
| 703 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 704 | |
David von Oheimb | 9fdcc21 | 2019-01-15 21:51:25 +0100 | [diff] [blame] | 705 | /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */ |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 706 | int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 707 | { |
| 708 | ASN1_OCTET_STRING *os = NULL; |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 709 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 710 | switch (OBJ_obj2nid(p7->type)) { |
| 711 | case NID_pkcs7_data: |
| 712 | os = p7->d.data; |
| 713 | break; |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 714 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 715 | case NID_pkcs7_signedAndEnveloped: |
| 716 | os = p7->d.signed_and_enveloped->enc_data->enc_data; |
| 717 | if (os == NULL) { |
Dr. Stephen Henson | f422a51 | 2015-03-14 04:16:42 +0000 | [diff] [blame] | 718 | os = ASN1_OCTET_STRING_new(); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 719 | p7->d.signed_and_enveloped->enc_data->enc_data = os; |
| 720 | } |
| 721 | break; |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 722 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 723 | case NID_pkcs7_enveloped: |
| 724 | os = p7->d.enveloped->enc_data->enc_data; |
| 725 | if (os == NULL) { |
Dr. Stephen Henson | f422a51 | 2015-03-14 04:16:42 +0000 | [diff] [blame] | 726 | os = ASN1_OCTET_STRING_new(); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 727 | p7->d.enveloped->enc_data->enc_data = os; |
| 728 | } |
| 729 | break; |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 730 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 731 | case NID_pkcs7_signed: |
| 732 | os = p7->d.sign->contents->d.data; |
| 733 | break; |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 734 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 735 | default: |
| 736 | os = NULL; |
| 737 | break; |
| 738 | } |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 739 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 740 | if (os == NULL) |
| 741 | return 0; |
Dr. Stephen Henson | 11d8cdc | 2006-12-24 16:22:56 +0000 | [diff] [blame] | 742 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 743 | os->flags |= ASN1_STRING_FLAG_NDEF; |
| 744 | *boundary = &os->data; |
| 745 | |
| 746 | return 1; |
| 747 | } |