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_x509.h" 18#include "ssl_methods.h" 19#include "ssl_dbg.h" 20#include "ssl_port.h" 21 22#include <assert.h> 23 24/** 25 * @brief show X509 certification information 26 */ 27int __X509_show_info(X509 *x) 28{ 29 return X509_METHOD_CALL(show_info, x); 30} 31 32/** 33 * @brief create a X509 certification object according to input X509 certification 34 */ 35X509* __X509_new(X509 *ix) 36{ 37 int ret; 38 X509 *x; 39 40 x = ssl_mem_zalloc(sizeof(X509)); 41 if (!x) { 42 SSL_DEBUG(SSL_X509_ERROR_LEVEL, "no enough memory > (x)"); 43 goto no_mem; 44 } 45 46 if (ix) 47 x->method = ix->method; 48 else 49 x->method = X509_method(); 50 51 ret = X509_METHOD_CALL(new, x, ix); 52 if (ret) { 53 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(new) return %d", ret); 54 goto failed; 55 } 56 57 return x; 58 59failed: 60 ssl_mem_free(x); 61no_mem: 62 return NULL; 63} 64 65/** 66 * @brief create a X509 certification object 67 */ 68X509* X509_new(void) 69{ 70 return __X509_new(NULL); 71} 72 73/** 74 * @brief free a X509 certification object 75 */ 76void X509_free(X509 *x) 77{ 78 SSL_ASSERT3(x); 79 80 X509_METHOD_CALL(free, x); 81 82 ssl_mem_free(x); 83}; 84 85/** 86 * @brief load a character certification context into system context. If '*cert' is pointed to the 87 * certification, then load certification into it. Or create a new X509 certification object 88 */ 89X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) 90{ 91 int m = 0; 92 int ret; 93 X509 *x; 94 95 SSL_ASSERT2(buffer); 96 SSL_ASSERT2(len); 97 98 if (cert && *cert) { 99 x = *cert; 100 } else { 101 x = X509_new(); 102 if (!x) { 103 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL"); 104 goto failed1; 105 } 106 m = 1; 107 } 108 109 ret = X509_METHOD_CALL(load, x, buffer, (int)len); 110 if (ret) { 111 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(load) return %d", ret); 112 goto failed2; 113 } 114 115 return x; 116 117failed2: 118 if (m) 119 X509_free(x); 120failed1: 121 return NULL; 122} 123 124/** 125 * @brief return SSL X509 verify parameters 126 */ 127 128X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) 129{ 130 return &ssl->param; 131} 132 133/** 134 * @brief set X509 host verification flags 135 */ 136 137int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, 138 unsigned long flags) 139{ 140 /* flags not supported yet */ 141 return 0; 142} 143 144/** 145 * @brief clear X509 host verification flags 146 */ 147 148int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param, 149 unsigned long flags) 150{ 151 /* flags not supported yet */ 152 return 0; 153} 154 155/** 156 * @brief set SSL context client CA certification 157 */ 158int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) 159{ 160 SSL_ASSERT1(ctx); 161 SSL_ASSERT1(x); 162 assert(ctx); 163 if (ctx->client_CA == x) 164 return 1; 165 166 X509_free(ctx->client_CA); 167 168 ctx->client_CA = x; 169 170 return 1; 171} 172 173/** 174 * @brief add CA client certification into the SSL 175 */ 176int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ctx, int len, 177 const unsigned char *d) 178{ 179 SSL_ASSERT1(ctx); 180 181 if (!d2i_X509(&ctx->client_CA, d, len)) { 182 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); 183 return 0; 184 } 185 186 return 1; 187} 188 189/** 190 * @brief add CA client certification into the SSL 191 */ 192int SSL_add_client_CA(SSL *ssl, X509 *x) 193{ 194 SSL_ASSERT1(ssl); 195 SSL_ASSERT1(x); 196 197 if (ssl->client_CA == x) 198 return 1; 199 200 X509_free(ssl->client_CA); 201 202 ssl->client_CA = x; 203 204 return 1; 205} 206 207/** 208 * @brief set the SSL context certification 209 */ 210int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) 211{ 212 SSL_ASSERT1(ctx); 213 SSL_ASSERT1(x); 214 215 if (ctx->cert->x509 == x) 216 return 1; 217 218 X509_free(ctx->cert->x509); 219 220 ctx->cert->x509 = x; 221 222 return 1; 223} 224 225/** 226 * @brief set the SSL certification 227 */ 228int SSL_use_certificate(SSL *ssl, X509 *x) 229{ 230 SSL_ASSERT1(ssl); 231 SSL_ASSERT1(x); 232 233 if (ssl->cert->x509 == x) 234 return 1; 235 236 X509_free(ssl->cert->x509); 237 238 ssl->cert->x509 = x; 239 240 return 1; 241} 242 243/** 244 * @brief get the SSL certification point 245 */ 246X509 *SSL_get_certificate(const SSL *ssl) 247{ 248 SSL_ASSERT2(ssl); 249 250 return ssl->cert->x509; 251} 252 253/** 254 * @brief load certification into the SSL context 255 */ 256int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, 257 const unsigned char *d) 258{ 259 int ret; 260 X509 *x; 261 262 x = d2i_X509(NULL, d, len); 263 if (!x) { 264 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); 265 goto failed1; 266 } 267 268 ret = SSL_CTX_use_certificate(ctx, x); 269 if (!ret) { 270 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_certificate() return %d", ret); 271 goto failed2; 272 } 273 274 return 1; 275 276failed2: 277 X509_free(x); 278failed1: 279 return 0; 280} 281 282/** 283 * @brief load certification into the SSL 284 */ 285int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) 286{ 287 int ret; 288 X509 *x; 289 290 x = d2i_X509(NULL, d, len); 291 if (!x) { 292 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); 293 goto failed1; 294 } 295 296 ret = SSL_use_certificate(ssl, x); 297 if (!ret) { 298 SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_certificate() return %d", ret); 299 goto failed2; 300 } 301 302 return 1; 303 304failed2: 305 X509_free(x); 306failed1: 307 return 0; 308} 309 310/** 311 * @brief load the certification file into SSL context 312 */ 313int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) 314{ 315 return 0; 316} 317 318/** 319 * @brief load the certification file into SSL 320 */ 321int SSL_use_certificate_file(SSL *ssl, const char *file, int type) 322{ 323 return 0; 324} 325 326/** 327 * @brief get peer certification 328 */ 329X509 *SSL_get_peer_certificate(const SSL *ssl) 330{ 331 SSL_ASSERT2(ssl); 332 333 return ssl->session->peer; 334} 335 336int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) 337{ 338 return X509_V_ERR_UNSPECIFIED; 339} 340 341int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) 342{ 343 return 0; 344} 345 346const char *X509_verify_cert_error_string(long n) 347{ 348 return "unknown"; 349} 350