Imported Upstream version 3.2.0
[platform/upstream/libwebsockets.git] / lib / tls / mbedtls / wrapper / library / ssl_pkey.c
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 }