xref: /openssl/crypto/pkcs12/p12_p8e.c (revision e077455e)
1 /*
2  * Copyright 2001-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 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/core.h>
13 #include <openssl/pkcs12.h>
14 #include "crypto/x509.h"
15 
PKCS8_encrypt_ex(int pbe_nid,const EVP_CIPHER * cipher,const char * pass,int passlen,unsigned char * salt,int saltlen,int iter,PKCS8_PRIV_KEY_INFO * p8inf,OSSL_LIB_CTX * libctx,const char * propq)16 X509_SIG *PKCS8_encrypt_ex(int pbe_nid, const EVP_CIPHER *cipher,
17                            const char *pass, int passlen,
18                            unsigned char *salt, int saltlen, int iter,
19                            PKCS8_PRIV_KEY_INFO *p8inf,
20                            OSSL_LIB_CTX *libctx, const char *propq)
21 {
22     X509_SIG *p8 = NULL;
23     X509_ALGOR *pbe;
24 
25     if (pbe_nid == -1) {
26         if (cipher == NULL) {
27             ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_NULL_PARAMETER);
28             return NULL;
29         }
30         pbe = PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, -1,
31                                    libctx);
32     } else {
33         ERR_set_mark();
34         if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) {
35             ERR_clear_last_mark();
36             if (cipher == NULL) {
37                 ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_NULL_PARAMETER);
38                 return NULL;
39             }
40             pbe = PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL,
41                                        pbe_nid, libctx);
42         } else {
43             ERR_pop_to_mark();
44             pbe = PKCS5_pbe_set_ex(pbe_nid, iter, salt, saltlen, libctx);
45         }
46     }
47     if (pbe == NULL) {
48         ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
49         return NULL;
50     }
51     p8 = PKCS8_set0_pbe_ex(pass, passlen, p8inf, pbe, libctx, propq);
52     if (p8 == NULL) {
53         X509_ALGOR_free(pbe);
54         return NULL;
55     }
56 
57     return p8;
58 }
59 
PKCS8_encrypt(int pbe_nid,const EVP_CIPHER * cipher,const char * pass,int passlen,unsigned char * salt,int saltlen,int iter,PKCS8_PRIV_KEY_INFO * p8inf)60 X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
61                         const char *pass, int passlen,
62                         unsigned char *salt, int saltlen, int iter,
63                         PKCS8_PRIV_KEY_INFO *p8inf)
64 {
65     return PKCS8_encrypt_ex(pbe_nid, cipher, pass, passlen, salt, saltlen, iter,
66                             p8inf, NULL, NULL);
67 }
68 
PKCS8_set0_pbe_ex(const char * pass,int passlen,PKCS8_PRIV_KEY_INFO * p8inf,X509_ALGOR * pbe,OSSL_LIB_CTX * ctx,const char * propq)69 X509_SIG *PKCS8_set0_pbe_ex(const char *pass, int passlen,
70                             PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe,
71                             OSSL_LIB_CTX *ctx, const char *propq)
72 {
73     X509_SIG *p8;
74     ASN1_OCTET_STRING *enckey;
75 
76     enckey =
77         PKCS12_item_i2d_encrypt_ex(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
78                                    pass, passlen, p8inf, 1, ctx, propq);
79     if (!enckey) {
80         ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR);
81         return NULL;
82     }
83 
84     p8 = OPENSSL_zalloc(sizeof(*p8));
85 
86     if (p8 == NULL) {
87         ASN1_OCTET_STRING_free(enckey);
88         return NULL;
89     }
90     p8->algor = pbe;
91     p8->digest = enckey;
92 
93     return p8;
94 }
95 
PKCS8_set0_pbe(const char * pass,int passlen,PKCS8_PRIV_KEY_INFO * p8inf,X509_ALGOR * pbe)96 X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
97                          PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
98 {
99     return PKCS8_set0_pbe_ex(pass, passlen, p8inf, pbe, NULL, NULL);
100 }
101