• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved.
3   *
4   * Licensed under the Apache License 2.0 (the "License").  You may not use
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
8   */
9  
10  /*
11   * Low level key APIs (DH etc) are deprecated for public use, but still ok for
12   * internal use.
13   */
14  #include "internal/deprecated.h"
15  
16  #include "internal/cryptlib.h"
17  #include <openssl/asn1t.h>
18  #include <openssl/pem.h>
19  #include <openssl/x509v3.h>
20  #include <openssl/err.h>
21  #include <openssl/cms.h>
22  #include <openssl/aes.h>
23  #include "cms_local.h"
24  #include "crypto/asn1.h"
25  
26  /* Key Agreement Recipient Info (KARI) routines */
27  
CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo * ri,X509_ALGOR ** palg,ASN1_OCTET_STRING ** pukm)28  int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
29                                      X509_ALGOR **palg,
30                                      ASN1_OCTET_STRING **pukm)
31  {
32      if (ri->type != CMS_RECIPINFO_AGREE) {
33          ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
34          return 0;
35      }
36      if (palg)
37          *palg = ri->d.kari->keyEncryptionAlgorithm;
38      if (pukm)
39          *pukm = ri->d.kari->ukm;
40      return 1;
41  }
42  
43  /* Retrieve recipient encrypted keys from a kari */
44  
STACK_OF(CMS_RecipientEncryptedKey)45  STACK_OF(CMS_RecipientEncryptedKey)
46  *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
47  {
48      if (ri->type != CMS_RECIPINFO_AGREE) {
49          ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
50          return NULL;
51      }
52      return ri->d.kari->recipientEncryptedKeys;
53  }
54  
CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo * ri,X509_ALGOR ** pubalg,ASN1_BIT_STRING ** pubkey,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)55  int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
56                                          X509_ALGOR **pubalg,
57                                          ASN1_BIT_STRING **pubkey,
58                                          ASN1_OCTET_STRING **keyid,
59                                          X509_NAME **issuer,
60                                          ASN1_INTEGER **sno)
61  {
62      CMS_OriginatorIdentifierOrKey *oik;
63  
64      if (ri->type != CMS_RECIPINFO_AGREE) {
65          ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
66          return 0;
67      }
68      oik = ri->d.kari->originator;
69      if (issuer)
70          *issuer = NULL;
71      if (sno)
72          *sno = NULL;
73      if (keyid)
74          *keyid = NULL;
75      if (pubalg)
76          *pubalg = NULL;
77      if (pubkey)
78          *pubkey = NULL;
79      if (oik->type == CMS_OIK_ISSUER_SERIAL) {
80          if (issuer)
81              *issuer = oik->d.issuerAndSerialNumber->issuer;
82          if (sno)
83              *sno = oik->d.issuerAndSerialNumber->serialNumber;
84      } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
85          if (keyid)
86              *keyid = oik->d.subjectKeyIdentifier;
87      } else if (oik->type == CMS_OIK_PUBKEY) {
88          if (pubalg)
89              *pubalg = oik->d.originatorKey->algorithm;
90          if (pubkey)
91              *pubkey = oik->d.originatorKey->publicKey;
92      } else
93          return 0;
94      return 1;
95  }
96  
CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo * ri,X509 * cert)97  int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
98  {
99      CMS_OriginatorIdentifierOrKey *oik;
100  
101      if (ri->type != CMS_RECIPINFO_AGREE) {
102          ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
103          return -2;
104      }
105      oik = ri->d.kari->originator;
106      if (oik->type == CMS_OIK_ISSUER_SERIAL)
107          return ossl_cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
108      else if (oik->type == CMS_OIK_KEYIDENTIFIER)
109          return ossl_cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
110      return -1;
111  }
112  
CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey * rek,ASN1_OCTET_STRING ** keyid,ASN1_GENERALIZEDTIME ** tm,CMS_OtherKeyAttribute ** other,X509_NAME ** issuer,ASN1_INTEGER ** sno)113  int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
114                                        ASN1_OCTET_STRING **keyid,
115                                        ASN1_GENERALIZEDTIME **tm,
116                                        CMS_OtherKeyAttribute **other,
117                                        X509_NAME **issuer, ASN1_INTEGER **sno)
118  {
119      CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
120  
121      if (rid->type == CMS_REK_ISSUER_SERIAL) {
122          if (issuer)
123              *issuer = rid->d.issuerAndSerialNumber->issuer;
124          if (sno)
125              *sno = rid->d.issuerAndSerialNumber->serialNumber;
126          if (keyid)
127              *keyid = NULL;
128          if (tm)
129              *tm = NULL;
130          if (other)
131              *other = NULL;
132      } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
133          if (keyid)
134              *keyid = rid->d.rKeyId->subjectKeyIdentifier;
135          if (tm)
136              *tm = rid->d.rKeyId->date;
137          if (other)
138              *other = rid->d.rKeyId->other;
139          if (issuer)
140              *issuer = NULL;
141          if (sno)
142              *sno = NULL;
143      } else
144          return 0;
145      return 1;
146  }
147  
CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey * rek,X509 * cert)148  int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
149                                         X509 *cert)
150  {
151      CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
152  
153      if (rid->type == CMS_REK_ISSUER_SERIAL)
154          return ossl_cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
155      else if (rid->type == CMS_REK_KEYIDENTIFIER)
156          return ossl_cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier,
157                                         cert);
158      else
159          return -1;
160  }
161  
CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo * ri,EVP_PKEY * pk,X509 * peer)162  int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri,
163                                                EVP_PKEY *pk, X509 *peer)
164  {
165      EVP_PKEY_CTX *pctx;
166      CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
167  
168      EVP_PKEY_CTX_free(kari->pctx);
169      kari->pctx = NULL;
170      if (pk == NULL)
171          return 1;
172  
173      pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(kari->cms_ctx),
174                                        pk,
175                                        ossl_cms_ctx_get0_propq(kari->cms_ctx));
176      if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0)
177          goto err;
178  
179      if (peer != NULL) {
180          EVP_PKEY *pub_pkey = X509_get0_pubkey(peer);
181  
182          if (EVP_PKEY_derive_set_peer(pctx, pub_pkey) <= 0)
183              goto err;
184      }
185  
186      kari->pctx = pctx;
187      return 1;
188   err:
189      EVP_PKEY_CTX_free(pctx);
190      return 0;
191  }
192  
CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo * ri,EVP_PKEY * pk)193  int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
194  {
195      return CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, NULL);
196  }
197  
CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo * ri)198  EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
199  {
200      if (ri->type == CMS_RECIPINFO_AGREE)
201          return ri->d.kari->ctx;
202      return NULL;
203  }
204  
205  /*
206   * Derive KEK and decrypt/encrypt with it to produce either the original CEK
207   * or the encrypted CEK.
208   */
209  
cms_kek_cipher(unsigned char ** pout,size_t * poutlen,const unsigned char * in,size_t inlen,CMS_KeyAgreeRecipientInfo * kari,int enc)210  static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
211                            const unsigned char *in, size_t inlen,
212                            CMS_KeyAgreeRecipientInfo *kari, int enc)
213  {
214      /* Key encryption key */
215      unsigned char kek[EVP_MAX_KEY_LENGTH];
216      size_t keklen;
217      int rv = 0;
218      unsigned char *out = NULL;
219      int outlen;
220  
221      keklen = EVP_CIPHER_CTX_get_key_length(kari->ctx);
222      if (keklen > EVP_MAX_KEY_LENGTH)
223          return 0;
224      /* Derive KEK */
225      if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
226          goto err;
227      /* Set KEK in context */
228      if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc))
229          goto err;
230      /* obtain output length of ciphered key */
231      if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen))
232          goto err;
233      out = OPENSSL_malloc(outlen);
234      if (out == NULL)
235          goto err;
236      if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen))
237          goto err;
238      *pout = out;
239      *poutlen = (size_t)outlen;
240      rv = 1;
241  
242   err:
243      OPENSSL_cleanse(kek, keklen);
244      if (!rv)
245          OPENSSL_free(out);
246      EVP_CIPHER_CTX_reset(kari->ctx);
247      /* FIXME: WHY IS kari->pctx freed here?  /RL */
248      EVP_PKEY_CTX_free(kari->pctx);
249      kari->pctx = NULL;
250      return rv;
251  }
252  
CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri,CMS_RecipientEncryptedKey * rek)253  int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
254                                     CMS_RecipientInfo *ri,
255                                     CMS_RecipientEncryptedKey *rek)
256  {
257      int rv = 0;
258      unsigned char *enckey = NULL, *cek = NULL;
259      size_t enckeylen;
260      size_t ceklen;
261      CMS_EncryptedContentInfo *ec;
262  
263      enckeylen = rek->encryptedKey->length;
264      enckey = rek->encryptedKey->data;
265      /* Setup all parameters to derive KEK */
266      if (!ossl_cms_env_asn1_ctrl(ri, 1))
267          goto err;
268      /* Attempt to decrypt CEK */
269      if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
270          goto err;
271      ec = ossl_cms_get0_env_enc_content(cms);
272      OPENSSL_clear_free(ec->key, ec->keylen);
273      ec->key = cek;
274      ec->keylen = ceklen;
275      cek = NULL;
276      rv = 1;
277   err:
278      OPENSSL_free(cek);
279      return rv;
280  }
281  
282  /* Create ephemeral key and initialise context based on it */
cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo * kari,EVP_PKEY * pk)283  static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
284                                           EVP_PKEY *pk)
285  {
286      EVP_PKEY_CTX *pctx = NULL;
287      EVP_PKEY *ekey = NULL;
288      int rv = 0;
289      const CMS_CTX *ctx = kari->cms_ctx;
290      OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx);
291      const char *propq = ossl_cms_ctx_get0_propq(ctx);
292  
293      pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propq);
294      if (pctx == NULL)
295          goto err;
296      if (EVP_PKEY_keygen_init(pctx) <= 0)
297          goto err;
298      if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
299          goto err;
300      EVP_PKEY_CTX_free(pctx);
301      pctx = EVP_PKEY_CTX_new_from_pkey(libctx, ekey, propq);
302      if (pctx == NULL)
303          goto err;
304      if (EVP_PKEY_derive_init(pctx) <= 0)
305          goto err;
306      kari->pctx = pctx;
307      rv = 1;
308   err:
309      if (!rv)
310          EVP_PKEY_CTX_free(pctx);
311      EVP_PKEY_free(ekey);
312      return rv;
313  }
314  
315  /* Set originator private key and initialise context based on it */
cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo * kari,EVP_PKEY * originatorPrivKey)316  static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari,
317                                                 EVP_PKEY *originatorPrivKey )
318  {
319      EVP_PKEY_CTX *pctx = NULL;
320      int rv = 0;
321      const CMS_CTX *ctx = kari->cms_ctx;
322  
323      pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
324                                        originatorPrivKey,
325                                        ossl_cms_ctx_get0_propq(ctx));
326      if (pctx == NULL)
327          goto err;
328      if (EVP_PKEY_derive_init(pctx) <= 0)
329           goto err;
330  
331      kari->pctx = pctx;
332      rv = 1;
333   err:
334      if (rv == 0)
335          EVP_PKEY_CTX_free(pctx);
336      return rv;
337  }
338  
339  /* Initialise a kari based on passed certificate and key */
340  
ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo * ri,X509 * recip,EVP_PKEY * recipPubKey,X509 * originator,EVP_PKEY * originatorPrivKey,unsigned int flags,const CMS_CTX * ctx)341  int ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri,  X509 *recip,
342                                       EVP_PKEY *recipPubKey, X509 *originator,
343                                       EVP_PKEY *originatorPrivKey,
344                                       unsigned int flags, const CMS_CTX *ctx)
345  {
346      CMS_KeyAgreeRecipientInfo *kari;
347      CMS_RecipientEncryptedKey *rek = NULL;
348  
349      ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
350      if (ri->d.kari == NULL)
351          return 0;
352      ri->type = CMS_RECIPINFO_AGREE;
353  
354      kari = ri->d.kari;
355      kari->version = 3;
356      kari->cms_ctx = ctx;
357  
358      rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
359      if (rek == NULL)
360          return 0;
361  
362      if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
363          M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
364          return 0;
365      }
366  
367      if (flags & CMS_USE_KEYID) {
368          rek->rid->type = CMS_REK_KEYIDENTIFIER;
369          rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
370          if (rek->rid->d.rKeyId == NULL)
371              return 0;
372          if (!ossl_cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
373              return 0;
374      } else {
375          rek->rid->type = CMS_REK_ISSUER_SERIAL;
376          if (!ossl_cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
377              return 0;
378      }
379  
380      if (originatorPrivKey == NULL && originator == NULL) {
381          /* Create ephemeral key */
382          if (!cms_kari_create_ephemeral_key(kari, recipPubKey))
383              return 0;
384      } else {
385          /* Use originator key */
386          CMS_OriginatorIdentifierOrKey *oik = ri->d.kari->originator;
387  
388          if (originatorPrivKey == NULL || originator == NULL)
389              return 0;
390  
391          if (flags & CMS_USE_ORIGINATOR_KEYID) {
392               oik->type = CMS_OIK_KEYIDENTIFIER;
393               oik->d.subjectKeyIdentifier = ASN1_OCTET_STRING_new();
394               if (oik->d.subjectKeyIdentifier == NULL)
395                    return 0;
396               if (!ossl_cms_set1_keyid(&oik->d.subjectKeyIdentifier, originator))
397                    return 0;
398          } else {
399               oik->type = CMS_REK_ISSUER_SERIAL;
400               if (!ossl_cms_set1_ias(&oik->d.issuerAndSerialNumber, originator))
401                    return 0;
402          }
403  
404          if (!cms_kari_set_originator_private_key(kari, originatorPrivKey))
405              return 0;
406      }
407  
408      EVP_PKEY_up_ref(recipPubKey);
409      rek->pkey = recipPubKey;
410      return 1;
411  }
412  
cms_wrap_init(CMS_KeyAgreeRecipientInfo * kari,const EVP_CIPHER * cipher)413  static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
414                           const EVP_CIPHER *cipher)
415  {
416      const CMS_CTX *cms_ctx = kari->cms_ctx;
417      EVP_CIPHER_CTX *ctx = kari->ctx;
418      const EVP_CIPHER *kekcipher;
419      EVP_CIPHER *fetched_kekcipher;
420      const char *kekcipher_name;
421      int keylen;
422      int ret;
423  
424      /* If a suitable wrap algorithm is already set nothing to do */
425      kekcipher = EVP_CIPHER_CTX_get0_cipher(ctx);
426      if (kekcipher != NULL) {
427          if (EVP_CIPHER_CTX_get_mode(ctx) != EVP_CIPH_WRAP_MODE)
428              return 0;
429          return 1;
430      }
431      if (cipher == NULL)
432          return 0;
433      keylen = EVP_CIPHER_get_key_length(cipher);
434      if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_GET_WRAP_CIPHER) != 0) {
435          ret = EVP_CIPHER_meth_get_ctrl(cipher)(NULL, EVP_CTRL_GET_WRAP_CIPHER,
436                                                 0, &kekcipher);
437          if (ret <= 0)
438               return 0;
439  
440          if (kekcipher != NULL) {
441               if (EVP_CIPHER_get_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
442                   return 0;
443               kekcipher_name = EVP_CIPHER_get0_name(kekcipher);
444               goto enc;
445          }
446      }
447  
448      /*
449       * Pick a cipher based on content encryption cipher. If it is DES3 use
450       * DES3 wrap otherwise use AES wrap similar to key size.
451       */
452  #ifndef OPENSSL_NO_DES
453      if (EVP_CIPHER_get_type(cipher) == NID_des_ede3_cbc)
454          kekcipher_name = SN_id_smime_alg_CMS3DESwrap;
455      else
456  #endif
457      if (keylen <= 16)
458          kekcipher_name = SN_id_aes128_wrap;
459      else if (keylen <= 24)
460          kekcipher_name = SN_id_aes192_wrap;
461      else
462          kekcipher_name = SN_id_aes256_wrap;
463  enc:
464      fetched_kekcipher = EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(cms_ctx),
465                                           kekcipher_name,
466                                           ossl_cms_ctx_get0_propq(cms_ctx));
467      if (fetched_kekcipher == NULL)
468          return 0;
469      ret = EVP_EncryptInit_ex(ctx, fetched_kekcipher, NULL, NULL, NULL);
470      EVP_CIPHER_free(fetched_kekcipher);
471      return ret;
472  }
473  
474  /* Encrypt content key in key agreement recipient info */
475  
ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo * cms,CMS_RecipientInfo * ri)476  int ossl_cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
477                                          CMS_RecipientInfo *ri)
478  {
479      CMS_KeyAgreeRecipientInfo *kari;
480      CMS_EncryptedContentInfo *ec;
481      CMS_RecipientEncryptedKey *rek;
482      STACK_OF(CMS_RecipientEncryptedKey) *reks;
483      int i;
484  
485      if (ri->type != CMS_RECIPINFO_AGREE) {
486          ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT);
487          return 0;
488      }
489      kari = ri->d.kari;
490      reks = kari->recipientEncryptedKeys;
491      ec = ossl_cms_get0_env_enc_content(cms);
492      /* Initialise wrap algorithm parameters */
493      if (!cms_wrap_init(kari, ec->cipher))
494          return 0;
495      /*
496       * If no originator key set up initialise for ephemeral key the public key
497       * ASN1 structure will set the actual public key value.
498       */
499      if (kari->originator->type == -1) {
500          CMS_OriginatorIdentifierOrKey *oik = kari->originator;
501          oik->type = CMS_OIK_PUBKEY;
502          oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
503          if (!oik->d.originatorKey)
504              return 0;
505      }
506      /* Initialise KDF algorithm */
507      if (!ossl_cms_env_asn1_ctrl(ri, 0))
508          return 0;
509      /* For each rek, derive KEK, encrypt CEK */
510      for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
511          unsigned char *enckey;
512          size_t enckeylen;
513          rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
514          if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
515              return 0;
516          if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
517                              kari, 1))
518              return 0;
519          ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
520      }
521  
522      return 1;
523  }
524