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