/* * Transfer binary data into the object loader. */ int ssl_obj_memory_load(SSL_CTX *ssl_ctx, int mem_type, const uint8_t *data, int len, const char *password) { int ret; SSLObjLoader *ssl_obj; ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); ssl_obj->buf = (uint8_t *)malloc(len); memcpy(ssl_obj->buf, data, len); ssl_obj->len = len; ret = do_obj(ssl_ctx, mem_type, ssl_obj, password); ssl_obj_free(ssl_obj); return ret; }
/* * Load a file into memory that is in binary DER (or ascii PEM) format. */ EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password) { #ifndef CONFIG_SSL_SKELETON_MODE static const char * const begin = "-----BEGIN"; int ret = SSL_OK; SSLObjLoader *ssl_obj = NULL; if (filename == NULL) { ret = SSL_ERROR_INVALID_KEY; goto error; } ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); ssl_obj->len = get_file(filename, &ssl_obj->buf); if (ssl_obj->len <= 0) { ret = SSL_ERROR_INVALID_KEY; goto error; } /* is the file a PEM file? */ if (strstr((char *)ssl_obj->buf, begin) != NULL) { #ifdef CONFIG_SSL_HAS_PEM ret = ssl_obj_PEM_load(ssl_ctx, obj_type, ssl_obj, password); #else #ifdef CONFIG_SSL_FULL_MODE printf("%s", unsupported_str); #endif ret = SSL_ERROR_NOT_SUPPORTED; #endif } else ret = do_obj(ssl_ctx, obj_type, ssl_obj, password); error: ssl_obj_free(ssl_obj); return ret; #else #ifdef CONFIG_SSL_FULL_MODE printf("%s", unsupported_str); #endif return SSL_ERROR_NOT_SUPPORTED; #endif /* CONFIG_SSL_SKELETON_MODE */ }
/** * Take a base64 blob of data and turn it into its proper ASN.1 form. */ static int new_pem_obj(SSL_CTX *ssl_ctx, int is_cacert, char *where, int remain, const char *password) { int ret = SSL_ERROR_BAD_CERTIFICATE; SSLObjLoader *ssl_obj = NULL; while (remain > 0) { int i, pem_size, obj_type; char *start = NULL, *end = NULL; for (i = 0; i < NUM_PEM_TYPES; i++) { if ((start = strstr(where, begins[i])) && (end = strstr(where, ends[i]))) { remain -= (int)(end - where); start += strlen(begins[i]); pem_size = (int)(end - start); ssl_obj = (SSLObjLoader *)calloc(1, sizeof(SSLObjLoader)); /* 4/3 bigger than what we need but so what */ ssl_obj->buf = (uint8_t *)calloc(1, pem_size); ssl_obj->len = pem_size; if (i == IS_RSA_PRIVATE_KEY && strstr(start, "Proc-Type:") && strstr(start, "4,ENCRYPTED")) { /* check for encrypted PEM file */ if (pem_decrypt(start, end, password, ssl_obj) < 0) { ret = SSL_ERROR_BAD_CERTIFICATE; goto error; } } else { ssl_obj->len = pem_size; if (base64_decode(start, pem_size, ssl_obj->buf, &ssl_obj->len) != 0) { ret = SSL_ERROR_BAD_CERTIFICATE; goto error; } } switch (i) { case IS_RSA_PRIVATE_KEY: obj_type = SSL_OBJ_RSA_KEY; break; case IS_ENCRYPTED_PRIVATE_KEY: case IS_PRIVATE_KEY: obj_type = SSL_OBJ_PKCS8; break; case IS_CERTIFICATE: obj_type = is_cacert ? SSL_OBJ_X509_CACERT : SSL_OBJ_X509_CERT; break; default: ret = SSL_ERROR_BAD_CERTIFICATE; goto error; } /* In a format we can now understand - so process it */ if ((ret = do_obj(ssl_ctx, obj_type, ssl_obj, password))) goto error; end += strlen(ends[i]); remain -= strlen(ends[i]); while (remain > 0 && (*end == '\r' || *end == '\n')) { end++; remain--; } where = end; break; } } ssl_obj_free(ssl_obj); ssl_obj = NULL; if (start == NULL) break; } error: ssl_obj_free(ssl_obj); return ret; }