• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "private-lib-core.h"
16 
17 #include "ssl_pkey.h"
18 #include "ssl_methods.h"
19 #include "ssl_dbg.h"
20 #include "ssl_port.h"
21 
22 /**
23  * @brief create a private key object according to input private key
24  */
__EVP_PKEY_new(EVP_PKEY * ipk,void * rngctx)25 EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk, void *rngctx)
26 {
27     int ret;
28     EVP_PKEY *pkey;
29 
30     pkey = ssl_mem_zalloc(sizeof(EVP_PKEY));
31     if (!pkey) {
32         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "no enough memory > (pkey)");
33         goto no_mem;
34     }
35 
36     if (ipk) {
37         pkey->method = ipk->method;
38     } else {
39         pkey->method = EVP_PKEY_method();
40     }
41 
42     ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk, rngctx);
43     if (ret) {
44         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(new) return %d", ret);
45         goto failed;
46     }
47 
48     return pkey;
49 
50 failed:
51     ssl_mem_free(pkey);
52 no_mem:
53     return NULL;
54 }
55 
56 /**
57  * @brief create a private key object
58  */
EVP_PKEY_new(void * rngctx)59 EVP_PKEY* EVP_PKEY_new(void *rngctx)
60 {
61     return __EVP_PKEY_new(NULL, rngctx);
62 }
63 
64 /**
65  * @brief free a private key object
66  */
EVP_PKEY_free(EVP_PKEY * pkey)67 void EVP_PKEY_free(EVP_PKEY *pkey)
68 {
69     SSL_ASSERT3(pkey);
70 
71     EVP_PKEY_METHOD_CALL(free, pkey);
72 
73     ssl_mem_free(pkey);
74 }
75 
76 /**
77  * @brief load a character key context into system context. If '*a' is pointed to the
78  *        private key, then load key into it. Or create a new private key object
79  */
d2i_PrivateKey(int type,EVP_PKEY ** a,const unsigned char ** pp,long length,void * rngctx)80 EVP_PKEY *d2i_PrivateKey(int type,
81                          EVP_PKEY **a,
82                          const unsigned char **pp,
83                          long length, void *rngctx)
84 {
85     int m = 0;
86     int ret;
87     EVP_PKEY *pkey;
88 
89     SSL_ASSERT2(pp);
90     SSL_ASSERT2(*pp);
91     SSL_ASSERT2(length);
92 
93     if (a && *a) {
94         pkey = *a;
95     } else {
96         pkey = EVP_PKEY_new(rngctx);
97         if (!pkey) {
98             SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_new() return NULL");
99             goto failed1;
100         }
101 
102         m = 1;
103     }
104 
105     ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, (int)length);
106     if (ret) {
107         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(load) return %d", ret);
108         goto failed2;
109     }
110 
111     if (a)
112         *a = pkey;
113 
114     return pkey;
115 
116 failed2:
117     if (m)
118         EVP_PKEY_free(pkey);
119 failed1:
120     return NULL;
121 }
122 
123 /**
124  * @brief set the SSL context private key
125  */
SSL_CTX_use_PrivateKey(SSL_CTX * ctx,EVP_PKEY * pkey)126 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
127 {
128     SSL_ASSERT1(ctx);
129     SSL_ASSERT1(pkey);
130 
131     if (ctx->cert->pkey == pkey)
132         return 1;
133 
134     if (ctx->cert->pkey)
135         EVP_PKEY_free(ctx->cert->pkey);
136 
137     ctx->cert->pkey = pkey;
138 
139     return 1;
140 }
141 
142 /**
143  * @brief set the SSL private key
144  */
SSL_use_PrivateKey(SSL * ssl,EVP_PKEY * pkey)145 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
146 {
147     SSL_ASSERT1(ssl);
148     SSL_ASSERT1(pkey);
149 
150     if (ssl->cert->pkey == pkey)
151         return 1;
152 
153     if (ssl->cert->pkey)
154         EVP_PKEY_free(ssl->cert->pkey);
155 
156     ssl->cert->pkey = pkey;
157 
158     return 1;
159 }
160 
161 /**
162  * @brief load private key into the SSL context
163  */
SSL_CTX_use_PrivateKey_ASN1(int type,SSL_CTX * ctx,const unsigned char * d,long len)164 int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
165                                 const unsigned char *d, long len)
166 {
167     int ret;
168     EVP_PKEY *pk;
169 
170     pk = d2i_PrivateKey(0, NULL, &d, len, ctx->rngctx);
171     if (!pk) {
172         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL");
173         goto failed1;
174     }
175 
176     ret = SSL_CTX_use_PrivateKey(ctx, pk);
177     if (!ret) {
178         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_PrivateKey() return %d", ret);
179         goto failed2;
180     }
181 
182     return 1;
183 
184 failed2:
185     EVP_PKEY_free(pk);
186 failed1:
187     return 0;
188 }
189 
190 /**
191  * @brief load private key into the SSL
192  */
SSL_use_PrivateKey_ASN1(int type,SSL * ssl,const unsigned char * d,long len)193 int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
194                                 const unsigned char *d, long len)
195 {
196     int ret;
197     EVP_PKEY *pk;
198 
199     pk = d2i_PrivateKey(0, NULL, &d, len, ssl->ctx->rngctx);
200     if (!pk) {
201         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL");
202         goto failed1;
203     }
204 
205     ret = SSL_use_PrivateKey(ssl, pk);
206     if (!ret) {
207         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_PrivateKey() return %d", ret);
208         goto failed2;
209     }
210 
211     return 1;
212 
213 failed2:
214     EVP_PKEY_free(pk);
215 failed1:
216     return 0;
217 }
218 
219 /**
220  * @brief load the private key file into SSL context
221  */
SSL_CTX_use_PrivateKey_file(SSL_CTX * ctx,const char * file,int type)222 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
223 {
224     return 0;
225 }
226 
227 /**
228  * @brief load the private key file into SSL
229  */
SSL_use_PrivateKey_file(SSL_CTX * ctx,const char * file,int type)230 int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
231 {
232     return 0;
233 }
234 
235 /**
236  * @brief load the RSA ASN1 private key into SSL context
237  */
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX * ctx,const unsigned char * d,long len)238 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
239 {
240     return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len);
241 }
242