diff options
Diffstat (limited to 'src/lib/libcrypto/cms/cms_kari.c')
-rw-r--r-- | src/lib/libcrypto/cms/cms_kari.c | 636 |
1 files changed, 318 insertions, 318 deletions
diff --git a/src/lib/libcrypto/cms/cms_kari.c b/src/lib/libcrypto/cms/cms_kari.c index 8a52d8401c..7aad3c755b 100644 --- a/src/lib/libcrypto/cms/cms_kari.c +++ b/src/lib/libcrypto/cms/cms_kari.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cms_kari.c,v 1.4 2019/08/10 16:39:17 jsing Exp $ */ | 1 | /* $OpenBSD: cms_kari.c,v 1.5 2019/08/10 16:42:20 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 3 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
4 | * project. | 4 | * project. |
@@ -65,19 +65,19 @@ | |||
65 | /* Key Agreement Recipient Info (KARI) routines */ | 65 | /* Key Agreement Recipient Info (KARI) routines */ |
66 | 66 | ||
67 | int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, | 67 | int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, |
68 | X509_ALGOR **palg, | 68 | X509_ALGOR **palg, |
69 | ASN1_OCTET_STRING **pukm) | 69 | ASN1_OCTET_STRING **pukm) |
70 | { | 70 | { |
71 | if (ri->type != CMS_RECIPINFO_AGREE) { | 71 | if (ri->type != CMS_RECIPINFO_AGREE) { |
72 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, | 72 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, |
73 | CMS_R_NOT_KEY_AGREEMENT); | 73 | CMS_R_NOT_KEY_AGREEMENT); |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | if (palg) | 76 | if (palg) |
77 | *palg = ri->d.kari->keyEncryptionAlgorithm; | 77 | *palg = ri->d.kari->keyEncryptionAlgorithm; |
78 | if (pukm) | 78 | if (pukm) |
79 | *pukm = ri->d.kari->ukm; | 79 | *pukm = ri->d.kari->ukm; |
80 | return 1; | 80 | return 1; |
81 | } | 81 | } |
82 | 82 | ||
83 | /* Retrieve recipient encrypted keys from a kari */ | 83 | /* Retrieve recipient encrypted keys from a kari */ |
@@ -85,142 +85,142 @@ int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, | |||
85 | STACK_OF(CMS_RecipientEncryptedKey) | 85 | STACK_OF(CMS_RecipientEncryptedKey) |
86 | *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) | 86 | *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) |
87 | { | 87 | { |
88 | if (ri->type != CMS_RECIPINFO_AGREE) { | 88 | if (ri->type != CMS_RECIPINFO_AGREE) { |
89 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, | 89 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, |
90 | CMS_R_NOT_KEY_AGREEMENT); | 90 | CMS_R_NOT_KEY_AGREEMENT); |
91 | return NULL; | 91 | return NULL; |
92 | } | 92 | } |
93 | return ri->d.kari->recipientEncryptedKeys; | 93 | return ri->d.kari->recipientEncryptedKeys; |
94 | } | 94 | } |
95 | 95 | ||
96 | int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, | 96 | int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, |
97 | X509_ALGOR **pubalg, | 97 | X509_ALGOR **pubalg, |
98 | ASN1_BIT_STRING **pubkey, | 98 | ASN1_BIT_STRING **pubkey, |
99 | ASN1_OCTET_STRING **keyid, | 99 | ASN1_OCTET_STRING **keyid, |
100 | X509_NAME **issuer, | 100 | X509_NAME **issuer, |
101 | ASN1_INTEGER **sno) | 101 | ASN1_INTEGER **sno) |
102 | { | 102 | { |
103 | CMS_OriginatorIdentifierOrKey *oik; | 103 | CMS_OriginatorIdentifierOrKey *oik; |
104 | if (ri->type != CMS_RECIPINFO_AGREE) { | 104 | if (ri->type != CMS_RECIPINFO_AGREE) { |
105 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, | 105 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, |
106 | CMS_R_NOT_KEY_AGREEMENT); | 106 | CMS_R_NOT_KEY_AGREEMENT); |
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | oik = ri->d.kari->originator; | 109 | oik = ri->d.kari->originator; |
110 | if (issuer) | 110 | if (issuer) |
111 | *issuer = NULL; | 111 | *issuer = NULL; |
112 | if (sno) | 112 | if (sno) |
113 | *sno = NULL; | 113 | *sno = NULL; |
114 | if (keyid) | 114 | if (keyid) |
115 | *keyid = NULL; | 115 | *keyid = NULL; |
116 | if (pubalg) | 116 | if (pubalg) |
117 | *pubalg = NULL; | 117 | *pubalg = NULL; |
118 | if (pubkey) | 118 | if (pubkey) |
119 | *pubkey = NULL; | 119 | *pubkey = NULL; |
120 | if (oik->type == CMS_OIK_ISSUER_SERIAL) { | 120 | if (oik->type == CMS_OIK_ISSUER_SERIAL) { |
121 | if (issuer) | 121 | if (issuer) |
122 | *issuer = oik->d.issuerAndSerialNumber->issuer; | 122 | *issuer = oik->d.issuerAndSerialNumber->issuer; |
123 | if (sno) | 123 | if (sno) |
124 | *sno = oik->d.issuerAndSerialNumber->serialNumber; | 124 | *sno = oik->d.issuerAndSerialNumber->serialNumber; |
125 | } else if (oik->type == CMS_OIK_KEYIDENTIFIER) { | 125 | } else if (oik->type == CMS_OIK_KEYIDENTIFIER) { |
126 | if (keyid) | 126 | if (keyid) |
127 | *keyid = oik->d.subjectKeyIdentifier; | 127 | *keyid = oik->d.subjectKeyIdentifier; |
128 | } else if (oik->type == CMS_OIK_PUBKEY) { | 128 | } else if (oik->type == CMS_OIK_PUBKEY) { |
129 | if (pubalg) | 129 | if (pubalg) |
130 | *pubalg = oik->d.originatorKey->algorithm; | 130 | *pubalg = oik->d.originatorKey->algorithm; |
131 | if (pubkey) | 131 | if (pubkey) |
132 | *pubkey = oik->d.originatorKey->publicKey; | 132 | *pubkey = oik->d.originatorKey->publicKey; |
133 | } else | 133 | } else |
134 | return 0; | 134 | return 0; |
135 | return 1; | 135 | return 1; |
136 | } | 136 | } |
137 | 137 | ||
138 | int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) | 138 | int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) |
139 | { | 139 | { |
140 | CMS_OriginatorIdentifierOrKey *oik; | 140 | CMS_OriginatorIdentifierOrKey *oik; |
141 | if (ri->type != CMS_RECIPINFO_AGREE) { | 141 | if (ri->type != CMS_RECIPINFO_AGREE) { |
142 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, | 142 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, |
143 | CMS_R_NOT_KEY_AGREEMENT); | 143 | CMS_R_NOT_KEY_AGREEMENT); |
144 | return -2; | 144 | return -2; |
145 | } | 145 | } |
146 | oik = ri->d.kari->originator; | 146 | oik = ri->d.kari->originator; |
147 | if (oik->type == CMS_OIK_ISSUER_SERIAL) | 147 | if (oik->type == CMS_OIK_ISSUER_SERIAL) |
148 | return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); | 148 | return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); |
149 | else if (oik->type == CMS_OIK_KEYIDENTIFIER) | 149 | else if (oik->type == CMS_OIK_KEYIDENTIFIER) |
150 | return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); | 150 | return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); |
151 | return -1; | 151 | return -1; |
152 | } | 152 | } |
153 | 153 | ||
154 | int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, | 154 | int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, |
155 | ASN1_OCTET_STRING **keyid, | 155 | ASN1_OCTET_STRING **keyid, |
156 | ASN1_GENERALIZEDTIME **tm, | 156 | ASN1_GENERALIZEDTIME **tm, |
157 | CMS_OtherKeyAttribute **other, | 157 | CMS_OtherKeyAttribute **other, |
158 | X509_NAME **issuer, ASN1_INTEGER **sno) | 158 | X509_NAME **issuer, ASN1_INTEGER **sno) |
159 | { | 159 | { |
160 | CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; | 160 | CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; |
161 | if (rid->type == CMS_REK_ISSUER_SERIAL) { | 161 | if (rid->type == CMS_REK_ISSUER_SERIAL) { |
162 | if (issuer) | 162 | if (issuer) |
163 | *issuer = rid->d.issuerAndSerialNumber->issuer; | 163 | *issuer = rid->d.issuerAndSerialNumber->issuer; |
164 | if (sno) | 164 | if (sno) |
165 | *sno = rid->d.issuerAndSerialNumber->serialNumber; | 165 | *sno = rid->d.issuerAndSerialNumber->serialNumber; |
166 | if (keyid) | 166 | if (keyid) |
167 | *keyid = NULL; | 167 | *keyid = NULL; |
168 | if (tm) | 168 | if (tm) |
169 | *tm = NULL; | 169 | *tm = NULL; |
170 | if (other) | 170 | if (other) |
171 | *other = NULL; | 171 | *other = NULL; |
172 | } else if (rid->type == CMS_REK_KEYIDENTIFIER) { | 172 | } else if (rid->type == CMS_REK_KEYIDENTIFIER) { |
173 | if (keyid) | 173 | if (keyid) |
174 | *keyid = rid->d.rKeyId->subjectKeyIdentifier; | 174 | *keyid = rid->d.rKeyId->subjectKeyIdentifier; |
175 | if (tm) | 175 | if (tm) |
176 | *tm = rid->d.rKeyId->date; | 176 | *tm = rid->d.rKeyId->date; |
177 | if (other) | 177 | if (other) |
178 | *other = rid->d.rKeyId->other; | 178 | *other = rid->d.rKeyId->other; |
179 | if (issuer) | 179 | if (issuer) |
180 | *issuer = NULL; | 180 | *issuer = NULL; |
181 | if (sno) | 181 | if (sno) |
182 | *sno = NULL; | 182 | *sno = NULL; |
183 | } else | 183 | } else |
184 | return 0; | 184 | return 0; |
185 | return 1; | 185 | return 1; |
186 | } | 186 | } |
187 | 187 | ||
188 | int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, | 188 | int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, |
189 | X509 *cert) | 189 | X509 *cert) |
190 | { | 190 | { |
191 | CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; | 191 | CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; |
192 | if (rid->type == CMS_REK_ISSUER_SERIAL) | 192 | if (rid->type == CMS_REK_ISSUER_SERIAL) |
193 | return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); | 193 | return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); |
194 | else if (rid->type == CMS_REK_KEYIDENTIFIER) | 194 | else if (rid->type == CMS_REK_KEYIDENTIFIER) |
195 | return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); | 195 | return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); |
196 | else | 196 | else |
197 | return -1; | 197 | return -1; |
198 | } | 198 | } |
199 | 199 | ||
200 | int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) | 200 | int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) |
201 | { | 201 | { |
202 | EVP_PKEY_CTX *pctx; | 202 | EVP_PKEY_CTX *pctx; |
203 | CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; | 203 | CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; |
204 | 204 | ||
205 | EVP_PKEY_CTX_free(kari->pctx); | 205 | EVP_PKEY_CTX_free(kari->pctx); |
206 | kari->pctx = NULL; | 206 | kari->pctx = NULL; |
207 | if (!pk) | 207 | if (!pk) |
208 | return 1; | 208 | return 1; |
209 | pctx = EVP_PKEY_CTX_new(pk, NULL); | 209 | pctx = EVP_PKEY_CTX_new(pk, NULL); |
210 | if (!pctx || !EVP_PKEY_derive_init(pctx)) | 210 | if (!pctx || !EVP_PKEY_derive_init(pctx)) |
211 | goto err; | 211 | goto err; |
212 | kari->pctx = pctx; | 212 | kari->pctx = pctx; |
213 | return 1; | 213 | return 1; |
214 | err: | 214 | err: |
215 | EVP_PKEY_CTX_free(pctx); | 215 | EVP_PKEY_CTX_free(pctx); |
216 | return 0; | 216 | return 0; |
217 | } | 217 | } |
218 | 218 | ||
219 | EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) | 219 | EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) |
220 | { | 220 | { |
221 | if (ri->type == CMS_RECIPINFO_AGREE) | 221 | if (ri->type == CMS_RECIPINFO_AGREE) |
222 | return ri->d.kari->ctx; | 222 | return ri->d.kari->ctx; |
223 | return NULL; | 223 | return NULL; |
224 | } | 224 | } |
225 | 225 | ||
226 | /* | 226 | /* |
@@ -229,231 +229,231 @@ EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) | |||
229 | */ | 229 | */ |
230 | 230 | ||
231 | static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, | 231 | static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, |
232 | const unsigned char *in, size_t inlen, | 232 | const unsigned char *in, size_t inlen, |
233 | CMS_KeyAgreeRecipientInfo *kari, int enc) | 233 | CMS_KeyAgreeRecipientInfo *kari, int enc) |
234 | { | 234 | { |
235 | /* Key encryption key */ | 235 | /* Key encryption key */ |
236 | unsigned char kek[EVP_MAX_KEY_LENGTH]; | 236 | unsigned char kek[EVP_MAX_KEY_LENGTH]; |
237 | size_t keklen; | 237 | size_t keklen; |
238 | int rv = 0; | 238 | int rv = 0; |
239 | unsigned char *out = NULL; | 239 | unsigned char *out = NULL; |
240 | int outlen; | 240 | int outlen; |
241 | keklen = EVP_CIPHER_CTX_key_length(kari->ctx); | 241 | keklen = EVP_CIPHER_CTX_key_length(kari->ctx); |
242 | if (keklen > EVP_MAX_KEY_LENGTH) | 242 | if (keklen > EVP_MAX_KEY_LENGTH) |
243 | return 0; | 243 | return 0; |
244 | /* Derive KEK */ | 244 | /* Derive KEK */ |
245 | if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0) | 245 | if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0) |
246 | goto err; | 246 | goto err; |
247 | /* Set KEK in context */ | 247 | /* Set KEK in context */ |
248 | if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc)) | 248 | if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc)) |
249 | goto err; | 249 | goto err; |
250 | /* obtain output length of ciphered key */ | 250 | /* obtain output length of ciphered key */ |
251 | if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen)) | 251 | if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen)) |
252 | goto err; | 252 | goto err; |
253 | out = OPENSSL_malloc(outlen); | 253 | out = OPENSSL_malloc(outlen); |
254 | if (out == NULL) | 254 | if (out == NULL) |
255 | goto err; | 255 | goto err; |
256 | if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen)) | 256 | if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen)) |
257 | goto err; | 257 | goto err; |
258 | *pout = out; | 258 | *pout = out; |
259 | *poutlen = (size_t)outlen; | 259 | *poutlen = (size_t)outlen; |
260 | rv = 1; | 260 | rv = 1; |
261 | 261 | ||
262 | err: | 262 | err: |
263 | OPENSSL_cleanse(kek, keklen); | 263 | OPENSSL_cleanse(kek, keklen); |
264 | if (!rv) | 264 | if (!rv) |
265 | OPENSSL_free(out); | 265 | OPENSSL_free(out); |
266 | EVP_CIPHER_CTX_reset(kari->ctx); | 266 | EVP_CIPHER_CTX_reset(kari->ctx); |
267 | /* FIXME: WHY IS kari->pctx freed here? /RL */ | 267 | /* FIXME: WHY IS kari->pctx freed here? /RL */ |
268 | EVP_PKEY_CTX_free(kari->pctx); | 268 | EVP_PKEY_CTX_free(kari->pctx); |
269 | kari->pctx = NULL; | 269 | kari->pctx = NULL; |
270 | return rv; | 270 | return rv; |
271 | } | 271 | } |
272 | 272 | ||
273 | int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, | 273 | int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, |
274 | CMS_RecipientInfo *ri, | 274 | CMS_RecipientInfo *ri, |
275 | CMS_RecipientEncryptedKey *rek) | 275 | CMS_RecipientEncryptedKey *rek) |
276 | { | 276 | { |
277 | int rv = 0; | 277 | int rv = 0; |
278 | unsigned char *enckey = NULL, *cek = NULL; | 278 | unsigned char *enckey = NULL, *cek = NULL; |
279 | size_t enckeylen; | 279 | size_t enckeylen; |
280 | size_t ceklen; | 280 | size_t ceklen; |
281 | CMS_EncryptedContentInfo *ec; | 281 | CMS_EncryptedContentInfo *ec; |
282 | enckeylen = rek->encryptedKey->length; | 282 | enckeylen = rek->encryptedKey->length; |
283 | enckey = rek->encryptedKey->data; | 283 | enckey = rek->encryptedKey->data; |
284 | /* Setup all parameters to derive KEK */ | 284 | /* Setup all parameters to derive KEK */ |
285 | if (!cms_env_asn1_ctrl(ri, 1)) | 285 | if (!cms_env_asn1_ctrl(ri, 1)) |
286 | goto err; | 286 | goto err; |
287 | /* Attempt to decrypt CEK */ | 287 | /* Attempt to decrypt CEK */ |
288 | if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) | 288 | if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) |
289 | goto err; | 289 | goto err; |
290 | ec = cms->d.envelopedData->encryptedContentInfo; | 290 | ec = cms->d.envelopedData->encryptedContentInfo; |
291 | OPENSSL_clear_free(ec->key, ec->keylen); | 291 | OPENSSL_clear_free(ec->key, ec->keylen); |
292 | ec->key = cek; | 292 | ec->key = cek; |
293 | ec->keylen = ceklen; | 293 | ec->keylen = ceklen; |
294 | cek = NULL; | 294 | cek = NULL; |
295 | rv = 1; | 295 | rv = 1; |
296 | err: | 296 | err: |
297 | OPENSSL_free(cek); | 297 | OPENSSL_free(cek); |
298 | return rv; | 298 | return rv; |
299 | } | 299 | } |
300 | 300 | ||
301 | /* Create ephemeral key and initialise context based on it */ | 301 | /* Create ephemeral key and initialise context based on it */ |
302 | static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, | 302 | static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, |
303 | EVP_PKEY *pk) | 303 | EVP_PKEY *pk) |
304 | { | 304 | { |
305 | EVP_PKEY_CTX *pctx = NULL; | 305 | EVP_PKEY_CTX *pctx = NULL; |
306 | EVP_PKEY *ekey = NULL; | 306 | EVP_PKEY *ekey = NULL; |
307 | int rv = 0; | 307 | int rv = 0; |
308 | pctx = EVP_PKEY_CTX_new(pk, NULL); | 308 | pctx = EVP_PKEY_CTX_new(pk, NULL); |
309 | if (!pctx) | 309 | if (!pctx) |
310 | goto err; | 310 | goto err; |
311 | if (EVP_PKEY_keygen_init(pctx) <= 0) | 311 | if (EVP_PKEY_keygen_init(pctx) <= 0) |
312 | goto err; | 312 | goto err; |
313 | if (EVP_PKEY_keygen(pctx, &ekey) <= 0) | 313 | if (EVP_PKEY_keygen(pctx, &ekey) <= 0) |
314 | goto err; | 314 | goto err; |
315 | EVP_PKEY_CTX_free(pctx); | 315 | EVP_PKEY_CTX_free(pctx); |
316 | pctx = EVP_PKEY_CTX_new(ekey, NULL); | 316 | pctx = EVP_PKEY_CTX_new(ekey, NULL); |
317 | if (!pctx) | 317 | if (!pctx) |
318 | goto err; | 318 | goto err; |
319 | if (EVP_PKEY_derive_init(pctx) <= 0) | 319 | if (EVP_PKEY_derive_init(pctx) <= 0) |
320 | goto err; | 320 | goto err; |
321 | kari->pctx = pctx; | 321 | kari->pctx = pctx; |
322 | rv = 1; | 322 | rv = 1; |
323 | err: | 323 | err: |
324 | if (!rv) | 324 | if (!rv) |
325 | EVP_PKEY_CTX_free(pctx); | 325 | EVP_PKEY_CTX_free(pctx); |
326 | EVP_PKEY_free(ekey); | 326 | EVP_PKEY_free(ekey); |
327 | return rv; | 327 | return rv; |
328 | } | 328 | } |
329 | 329 | ||
330 | /* Initialise a kari based on passed certificate and key */ | 330 | /* Initialise a kari based on passed certificate and key */ |
331 | 331 | ||
332 | int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, | 332 | int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, |
333 | EVP_PKEY *pk, unsigned int flags) | 333 | EVP_PKEY *pk, unsigned int flags) |
334 | { | 334 | { |
335 | CMS_KeyAgreeRecipientInfo *kari; | 335 | CMS_KeyAgreeRecipientInfo *kari; |
336 | CMS_RecipientEncryptedKey *rek = NULL; | 336 | CMS_RecipientEncryptedKey *rek = NULL; |
337 | 337 | ||
338 | ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo); | 338 | ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo); |
339 | if (!ri->d.kari) | 339 | if (!ri->d.kari) |
340 | return 0; | 340 | return 0; |
341 | ri->type = CMS_RECIPINFO_AGREE; | 341 | ri->type = CMS_RECIPINFO_AGREE; |
342 | 342 | ||
343 | kari = ri->d.kari; | 343 | kari = ri->d.kari; |
344 | kari->version = 3; | 344 | kari->version = 3; |
345 | 345 | ||
346 | rek = M_ASN1_new_of(CMS_RecipientEncryptedKey); | 346 | rek = M_ASN1_new_of(CMS_RecipientEncryptedKey); |
347 | if (rek == NULL) | 347 | if (rek == NULL) |
348 | return 0; | 348 | return 0; |
349 | 349 | ||
350 | if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { | 350 | if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { |
351 | M_ASN1_free_of(rek, CMS_RecipientEncryptedKey); | 351 | M_ASN1_free_of(rek, CMS_RecipientEncryptedKey); |
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | 354 | ||
355 | if (flags & CMS_USE_KEYID) { | 355 | if (flags & CMS_USE_KEYID) { |
356 | rek->rid->type = CMS_REK_KEYIDENTIFIER; | 356 | rek->rid->type = CMS_REK_KEYIDENTIFIER; |
357 | rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier); | 357 | rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier); |
358 | if (rek->rid->d.rKeyId == NULL) | 358 | if (rek->rid->d.rKeyId == NULL) |
359 | return 0; | 359 | return 0; |
360 | if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) | 360 | if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) |
361 | return 0; | 361 | return 0; |
362 | } else { | 362 | } else { |
363 | rek->rid->type = CMS_REK_ISSUER_SERIAL; | 363 | rek->rid->type = CMS_REK_ISSUER_SERIAL; |
364 | if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) | 364 | if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) |
365 | return 0; | 365 | return 0; |
366 | } | 366 | } |
367 | 367 | ||
368 | /* Create ephemeral key */ | 368 | /* Create ephemeral key */ |
369 | if (!cms_kari_create_ephemeral_key(kari, pk)) | 369 | if (!cms_kari_create_ephemeral_key(kari, pk)) |
370 | return 0; | 370 | return 0; |
371 | 371 | ||
372 | EVP_PKEY_up_ref(pk); | 372 | EVP_PKEY_up_ref(pk); |
373 | rek->pkey = pk; | 373 | rek->pkey = pk; |
374 | return 1; | 374 | return 1; |
375 | } | 375 | } |
376 | 376 | ||
377 | static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, | 377 | static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, |
378 | const EVP_CIPHER *cipher) | 378 | const EVP_CIPHER *cipher) |
379 | { | 379 | { |
380 | EVP_CIPHER_CTX *ctx = kari->ctx; | 380 | EVP_CIPHER_CTX *ctx = kari->ctx; |
381 | const EVP_CIPHER *kekcipher; | 381 | const EVP_CIPHER *kekcipher; |
382 | int keylen = EVP_CIPHER_key_length(cipher); | 382 | int keylen = EVP_CIPHER_key_length(cipher); |
383 | /* If a suitable wrap algorithm is already set nothing to do */ | 383 | /* If a suitable wrap algorithm is already set nothing to do */ |
384 | kekcipher = EVP_CIPHER_CTX_cipher(ctx); | 384 | kekcipher = EVP_CIPHER_CTX_cipher(ctx); |
385 | 385 | ||
386 | if (kekcipher) { | 386 | if (kekcipher) { |
387 | if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) | 387 | if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) |
388 | return 0; | 388 | return 0; |
389 | return 1; | 389 | return 1; |
390 | } | 390 | } |
391 | /* | 391 | /* |
392 | * Pick a cipher based on content encryption cipher. If it is DES3 use | 392 | * Pick a cipher based on content encryption cipher. If it is DES3 use |
393 | * DES3 wrap otherwise use AES wrap similar to key size. | 393 | * DES3 wrap otherwise use AES wrap similar to key size. |
394 | */ | 394 | */ |
395 | #ifndef OPENSSL_NO_DES | 395 | #ifndef OPENSSL_NO_DES |
396 | if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) | 396 | if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) |
397 | kekcipher = EVP_des_ede3_wrap(); | 397 | kekcipher = EVP_des_ede3_wrap(); |
398 | else | 398 | else |
399 | #endif | 399 | #endif |
400 | if (keylen <= 16) | 400 | if (keylen <= 16) |
401 | kekcipher = EVP_aes_128_wrap(); | 401 | kekcipher = EVP_aes_128_wrap(); |
402 | else if (keylen <= 24) | 402 | else if (keylen <= 24) |
403 | kekcipher = EVP_aes_192_wrap(); | 403 | kekcipher = EVP_aes_192_wrap(); |
404 | else | 404 | else |
405 | kekcipher = EVP_aes_256_wrap(); | 405 | kekcipher = EVP_aes_256_wrap(); |
406 | return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); | 406 | return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); |
407 | } | 407 | } |
408 | 408 | ||
409 | /* Encrypt content key in key agreement recipient info */ | 409 | /* Encrypt content key in key agreement recipient info */ |
410 | 410 | ||
411 | int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, | 411 | int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, |
412 | CMS_RecipientInfo *ri) | 412 | CMS_RecipientInfo *ri) |
413 | { | 413 | { |
414 | CMS_KeyAgreeRecipientInfo *kari; | 414 | CMS_KeyAgreeRecipientInfo *kari; |
415 | CMS_EncryptedContentInfo *ec; | 415 | CMS_EncryptedContentInfo *ec; |
416 | CMS_RecipientEncryptedKey *rek; | 416 | CMS_RecipientEncryptedKey *rek; |
417 | STACK_OF(CMS_RecipientEncryptedKey) *reks; | 417 | STACK_OF(CMS_RecipientEncryptedKey) *reks; |
418 | int i; | 418 | int i; |
419 | 419 | ||
420 | if (ri->type != CMS_RECIPINFO_AGREE) { | 420 | if (ri->type != CMS_RECIPINFO_AGREE) { |
421 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT); | 421 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT); |
422 | return 0; | 422 | return 0; |
423 | } | 423 | } |
424 | kari = ri->d.kari; | 424 | kari = ri->d.kari; |
425 | reks = kari->recipientEncryptedKeys; | 425 | reks = kari->recipientEncryptedKeys; |
426 | ec = cms->d.envelopedData->encryptedContentInfo; | 426 | ec = cms->d.envelopedData->encryptedContentInfo; |
427 | /* Initialise wrap algorithm parameters */ | 427 | /* Initialise wrap algorithm parameters */ |
428 | if (!cms_wrap_init(kari, ec->cipher)) | 428 | if (!cms_wrap_init(kari, ec->cipher)) |
429 | return 0; | 429 | return 0; |
430 | /* | 430 | /* |
431 | * If no originator key set up initialise for ephemeral key the public key | 431 | * If no originator key set up initialise for ephemeral key the public key |
432 | * ASN1 structure will set the actual public key value. | 432 | * ASN1 structure will set the actual public key value. |
433 | */ | 433 | */ |
434 | if (kari->originator->type == -1) { | 434 | if (kari->originator->type == -1) { |
435 | CMS_OriginatorIdentifierOrKey *oik = kari->originator; | 435 | CMS_OriginatorIdentifierOrKey *oik = kari->originator; |
436 | oik->type = CMS_OIK_PUBKEY; | 436 | oik->type = CMS_OIK_PUBKEY; |
437 | oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey); | 437 | oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey); |
438 | if (!oik->d.originatorKey) | 438 | if (!oik->d.originatorKey) |
439 | return 0; | 439 | return 0; |
440 | } | 440 | } |
441 | /* Initialise KDF algorithm */ | 441 | /* Initialise KDF algorithm */ |
442 | if (!cms_env_asn1_ctrl(ri, 0)) | 442 | if (!cms_env_asn1_ctrl(ri, 0)) |
443 | return 0; | 443 | return 0; |
444 | /* For each rek, derive KEK, encrypt CEK */ | 444 | /* For each rek, derive KEK, encrypt CEK */ |
445 | for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { | 445 | for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { |
446 | unsigned char *enckey; | 446 | unsigned char *enckey; |
447 | size_t enckeylen; | 447 | size_t enckeylen; |
448 | rek = sk_CMS_RecipientEncryptedKey_value(reks, i); | 448 | rek = sk_CMS_RecipientEncryptedKey_value(reks, i); |
449 | if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0) | 449 | if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0) |
450 | return 0; | 450 | return 0; |
451 | if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen, | 451 | if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen, |
452 | kari, 1)) | 452 | kari, 1)) |
453 | return 0; | 453 | return 0; |
454 | ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen); | 454 | ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen); |
455 | } | 455 | } |
456 | 456 | ||
457 | return 1; | 457 | return 1; |
458 | 458 | ||
459 | } | 459 | } |