Skip to content

Instantly share code, notes, and snippets.

@aido
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aido/9490244 to your computer and use it in GitHub Desktop.
Save aido/9490244 to your computer and use it in GitHub Desktop.
A DER decode test for OpenSSL and PolarSSL
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include <polarssl/entropy.h>
#include <polarssl/ctr_drbg.h>
#include <polarssl/pk.h>
/* Initialise DER encoded key string*/
const char privkey_str[] = "3081d302010104208ea106a78201d7bfc11af5c9230803db1eb104e0a4f47fa3af4a23a785584206a08185308182020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a12403220002a6ce40504bd48f6e71eaa27784705ba457463fb3b746e881350a09af2b850afc";
bool decode_hex(void *p, size_t max_len, const char *hexstr, size_t *out_len_)
{
static const unsigned char hexdigit_val[256] = {
['0'] = 0,
['1'] = 1,
['2'] = 2,
['3'] = 3,
['4'] = 4,
['5'] = 5,
['6'] = 6,
['7'] = 7,
['8'] = 8,
['9'] = 9,
['a'] = 0xa,
['b'] = 0xb,
['c'] = 0xc,
['d'] = 0xd,
['e'] = 0xe,
['f'] = 0xf,
['A'] = 0xa,
['B'] = 0xb,
['C'] = 0xc,
['D'] = 0xd,
['E'] = 0xe,
['F'] = 0xf,};
if (!p || !hexstr)
return false;
if (!strncmp(hexstr, "0x", 2))
hexstr += 2;
if (strlen(hexstr) > (max_len * 2))
return false;
unsigned char *buf = p;
size_t out_len = 0;
while (*hexstr) {
unsigned char c1 = (unsigned char) hexstr[0];
unsigned char c2 = (unsigned char) hexstr[1];
unsigned char v1 = hexdigit_val[c1];
unsigned char v2 = hexdigit_val[c2];
if (!v1 && (c1 != '0'))
return false;
if (!v2 && (c2 != '0'))
return false;
*buf = (v1 << 4) | v2;
out_len++;
buf++;
hexstr += 2;
}
if (out_len_)
*out_len_ = out_len;
return true;
}
int main ()
{
char rawbuf[strlen(privkey_str)];
size_t privkey_len = 0;
int ret = 1;
fprintf(stdout,"Starting: Key is %s\n", privkey_str);
/* Decode DER string to HEX */
if (decode_hex(rawbuf, sizeof(rawbuf), privkey_str, &privkey_len) != true) {
fprintf(stderr,"Error: decode_hex failed\n");
return ret;
}
fprintf(stdout,"decode_hex: OK\n");
/* Decode DER encoded private key using OpenSSL */
EC_KEY *open_key;
const unsigned char *privkey = rawbuf;
open_key = EC_KEY_new_by_curve_name(NID_secp256k1);
if (!open_key) {
fprintf(stderr,"Error: failed to init OpenSSL key\n");
return ret;
}
fprintf(stdout,"OpenSSL EC_KEY_new_by_curve_name: OK\n");
if (!d2i_ECPrivateKey(&open_key, &privkey, privkey_len)) {
fprintf(stderr,"Error: OpenSSL d2i_ECPrivateKey failed\n");
return ret;
}
fprintf(stdout,"OpenSSL d2i_ECPrivateKey: OK\n");
if (!EC_KEY_check_key(open_key)) {
fprintf(stderr,"Error: OpenSSL EC_KEY_check_key failed\n");
return ret;
}
fprintf(stdout,"OpenSSL EC_KEY_check_key: OK\n");
if (open_key) {
EC_KEY_free(open_key);
open_key = NULL;
}
fprintf(stdout,"OpenSSL EC_KEY_free: OK\n");
/* Parse DER encoded private key using PolarSSL */
pk_context polar_ctx;
pk_init(&polar_ctx);
if ( (ret = pk_parse_key(&polar_ctx, privkey, privkey_len, NULL, 0)) != 0 ) {
fprintf(stderr,"Error: PolarSSL pk_parse_key failed : %i\n", ret);
return ret;
}
if (pk_can_do(&polar_ctx, POLARSSL_PK_ECDSA) != 1 ) {
fprintf(stderr,"Error: PolarSSL pk_can_do failed\n");
return ret;
}
fprintf(stdout,"PolarSSL pk_can_do: OK\n");
if (&polar_ctx) {
pk_free(&polar_ctx);
}
fprintf(stdout,"PolarSSL pk_free: OK\n");
fprintf(stdout,"Success: All keys parsed OK\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment