• 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 "ssl_pkey.h"
16 #include "ssl_methods.h"
17 #include "ssl_dbg.h"
18 #include "ssl_port.h"
19 
20 /**
21  * @brief create a private key object according to input private key
22  */
__EVP_PKEY_new(EVP_PKEY * ipk)23 EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk)
24 {
25     int ret;
26     EVP_PKEY *pkey;
27 
28     pkey = ssl_mem_zalloc(sizeof(EVP_PKEY));
29     if (!pkey) {
30         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "no enough memory > (pkey)");
31         goto no_mem;
32     }
33 
34     if (ipk) {
35         pkey->method = ipk->method;
36     } else {
37         pkey->method = EVP_PKEY_method();
38     }
39 
40     ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk);
41     if (ret) {
42         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(new) return %d", ret);
43         goto failed;
44     }
45 
46     return pkey;
47 
48 failed:
49     ssl_mem_free(pkey);
50 no_mem:
51     return NULL;
52 }
53 
54 /**
55  * @brief create a private key object
56  */
EVP_PKEY_new(void)57 EVP_PKEY* EVP_PKEY_new(void)
58 {
59     return __EVP_PKEY_new(NULL);
60 }
61 
62 /**
63  * @brief free a private key object
64  */
EVP_PKEY_free(EVP_PKEY * pkey)65 void EVP_PKEY_free(EVP_PKEY *pkey)
66 {
67     SSL_ASSERT3(pkey);
68 
69     EVP_PKEY_METHOD_CALL(free, pkey);
70 
71     ssl_mem_free(pkey);
72 }
73 
74 /**
75  * @brief load a character key context into system context. If '*a' is pointed to the
76  *        private key, then load key into it. Or create a new private key object
77  */
d2i_PrivateKey(int type,EVP_PKEY ** a,const unsigned char ** pp,long length)78 EVP_PKEY *d2i_PrivateKey(int type,
79                          EVP_PKEY **a,
80                          const unsigned char **pp,
81                          long length)
82 {
83     int m = 0;
84     int ret;
85     EVP_PKEY *pkey;
86 
87     SSL_ASSERT2(pp);
88     SSL_ASSERT2(*pp);
89     SSL_ASSERT2(length);
90 
91     if (a && *a) {
92         pkey = *a;
93     } else {
94         pkey = EVP_PKEY_new();;
95         if (!pkey) {
96             SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_new() return NULL");
97             goto failed1;
98         }
99 
100         m = 1;
101     }
102 
103     ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length);
104     if (ret) {
105         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(load) return %d", ret);
106         goto failed2;
107     }
108 
109     if (a)
110         *a = pkey;
111 
112     return pkey;
113 
114 failed2:
115     if (m)
116         EVP_PKEY_free(pkey);
117 failed1:
118     return NULL;
119 }
120 
121 /**
122  * @brief set the SSL context private key
123  */
SSL_CTX_use_PrivateKey(SSL_CTX * ctx,EVP_PKEY * pkey)124 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
125 {
126     SSL_ASSERT1(ctx);
127     SSL_ASSERT1(pkey);
128 
129     if (ctx->cert->pkey == pkey)
130         return 1;
131 
132     if (ctx->cert->pkey)
133         EVP_PKEY_free(ctx->cert->pkey);
134 
135     ctx->cert->pkey = pkey;
136 
137     return 1;
138 }
139 
140 /**
141  * @brief set the SSL private key
142  */
SSL_use_PrivateKey(SSL * ssl,EVP_PKEY * pkey)143 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
144 {
145     SSL_ASSERT1(ssl);
146     SSL_ASSERT1(pkey);
147 
148     if (ssl->cert->pkey == pkey)
149         return 1;
150 
151     if (ssl->cert->pkey)
152         EVP_PKEY_free(ssl->cert->pkey);
153 
154     ssl->cert->pkey = pkey;
155 
156     return 1;
157 }
158 
159 /**
160  * @brief load private key into the SSL context
161  */
SSL_CTX_use_PrivateKey_ASN1(int type,SSL_CTX * ctx,const unsigned char * d,long len)162 int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
163                                 const unsigned char *d, long len)
164 {
165     int ret;
166     EVP_PKEY *pk;
167 
168     pk = d2i_PrivateKey(0, NULL, &d, len);
169     if (!pk) {
170         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL");
171         goto failed1;
172     }
173 
174     ret = SSL_CTX_use_PrivateKey(ctx, pk);
175     if (!ret) {
176         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_PrivateKey() return %d", ret);
177         goto failed2;
178     }
179 
180     return 1;
181 
182 failed2:
183     EVP_PKEY_free(pk);
184 failed1:
185     return 0;
186 }
187 
188 /**
189  * @brief load private key into the SSL
190  */
SSL_use_PrivateKey_ASN1(int type,SSL * ssl,const unsigned char * d,long len)191 int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
192                                 const unsigned char *d, long len)
193 {
194     int ret;
195     EVP_PKEY *pk;
196 
197     pk = d2i_PrivateKey(0, NULL, &d, len);
198     if (!pk) {
199         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL");
200         goto failed1;
201     }
202 
203     ret = SSL_use_PrivateKey(ssl, pk);
204     if (!ret) {
205         SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_PrivateKey() return %d", ret);
206         goto failed2;
207     }
208 
209     return 1;
210 
211 failed2:
212     EVP_PKEY_free(pk);
213 failed1:
214     return 0;
215 }
216 
217 /**
218  * @brief load the private key file into SSL context
219  */
SSL_CTX_use_PrivateKey_file(SSL_CTX * ctx,const char * file,int type)220 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
221 {
222     return 0;
223 }
224 
225 /**
226  * @brief load the private key file into SSL
227  */
SSL_use_PrivateKey_file(SSL_CTX * ctx,const char * file,int type)228 int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
229 {
230     return 0;
231 }
232 
233 /**
234  * @brief load the RSA ASN1 private key into SSL context
235  */
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX * ctx,const unsigned char * d,long len)236 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
237 {
238     return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len);
239 }
240