| /** | |
| * @file configCmdGet.c | |
| * @author NXP Semiconductors | |
| * @version 1.0 | |
| * @par License | |
| * | |
| * Copyright 2018 NXP | |
| * SPDX-License-Identifier: Apache-2.0 | |
| * | |
| * @par Description | |
| * Command handling for 'get'. Includes optional console handling | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <assert.h> | |
| // project specific include files | |
| #include "sm_types.h" | |
| #include "sm_apdu.h" | |
| #include "tst_sm_util.h" | |
| #include "tst_a71ch_util.h" | |
| #include "probeAxUtil.h" | |
| #include "configCmd.h" | |
| #include "configCli.h" | |
| #include "a71_debug.h" | |
| #include "HLSEAPI.h" | |
| #include "axHostCrypto.h" | |
| #include "tstHostCrypto.h" | |
| #ifdef OPENSSL | |
| #include <openssl/pem.h> | |
| #endif | |
| #define FLOW_VERBOSE_PROBE_A70 | |
| #ifdef FLOW_VERBOSE_PROBE_A70 | |
| #define FPRINTF(...) printf (__VA_ARGS__) | |
| #else | |
| #define FPRINTF(...) | |
| #endif | |
| // Warning: defining DBG_PROBE_A70 also exposes Private Key being set in log | |
| // #define DBG_PROBE_A70 | |
| #ifdef DBG_PROBE_A70 | |
| #define DBGPRINTF(...) printf (__VA_ARGS__) | |
| #else | |
| #define DBGPRINTF(...) | |
| #endif | |
| /** | |
| * a7xConfigCmdGetPub - get public key from pub key or key pair and save it in PEM format to file | |
| */ | |
| int a7xConfigCmdGetPub(int index, int type, char *szFilename, U16 *sw) { | |
| HLSE_RET_CODE nRet = AX_CLI_EXEC_FAILED; | |
| eccKeyComponents_t eccKc; | |
| FILE * pFile = NULL; | |
| char *buff = NULL; | |
| EC_KEY *eckey = NULL; | |
| BIO *out = BIO_new(BIO_s_mem()); | |
| BUF_MEM *bptr = NULL; | |
| unsigned char * pubuf; | |
| // Initialize data structure | |
| eccKc.bits = 256; | |
| eccKc.curve = ECCCurve_NIST_P256; | |
| eccKc.pubLen = sizeof(eccKc.pub); | |
| eccKc.privLen = sizeof(eccKc.priv); | |
| // Read public ECC key from card | |
| switch (type) | |
| { | |
| case A71_KEY_PUB_PAIR: | |
| *sw = A71_GetPublicKeyEccKeyPair((U8)index, eccKc.pub, &eccKc.pubLen); | |
| if (*sw != SW_OK) { return nRet; } | |
| break; | |
| case A71_KEY_PUBLIC_KEY: | |
| *sw = A71_GetEccPublicKey((U8)index, eccKc.pub, &eccKc.pubLen); | |
| if (*sw != SW_OK) { return nRet; } | |
| break; | |
| default: | |
| return nRet; | |
| break; | |
| } | |
| // Convert public key buffer to PEM format | |
| bptr = BUF_MEM_new(); | |
| eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); | |
| EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE); | |
| pubuf = (unsigned char *) malloc(4096 * sizeof(unsigned char)); | |
| memcpy(pubuf, eccKc.pub, (long)eccKc.pubLen); | |
| eckey = o2i_ECPublicKey(&eckey, (const unsigned char **)&pubuf, (long)eccKc.pubLen); | |
| PEM_write_bio_EC_PUBKEY(out, eckey); | |
| BIO_get_mem_ptr(out, &bptr); | |
| BIO_set_close(out, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */ | |
| buff = (char *)malloc(bptr->length); //converting BUF_MEM to Char * | |
| if (buff == NULL) { | |
| BIO_free_all(out); | |
| return AX_CLI_DYN_ALLOC_ERROR; | |
| } | |
| memcpy(buff, bptr->data, bptr->length - 1); //to be used later | |
| buff[bptr->length - 1] = 0; | |
| BIO_free_all(out); | |
| // Save PEM file to buffer | |
| pFile = fopen(szFilename, "w"); | |
| if (pFile) { | |
| fwrite(buff, bptr->length-1, 1, pFile); | |
| free(buff); | |
| fclose(pFile); | |
| } | |
| else { | |
| free(buff); | |
| return AX_CLI_EXEC_FAILED; | |
| } | |
| return AX_CLI_EXEC_OK; | |
| } |