diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index 0e57b37c1..2135d8aa0 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -382,6 +382,8 @@ int ecc_copy_curve(const ecc_key *srckey, ecc_key *key); int ecc_set_curve_by_size(int size, ecc_key *key); int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key); int ecc_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, ecc_key *key); +int ecc_import_with_curve(const unsigned char *in, unsigned long inlen, int type, ecc_key *key); +int ecc_import_with_oid(const unsigned char *in, unsigned long inlen, unsigned long *oid, unsigned long oid_len, int type, ecc_key *key); #ifdef LTC_SSH int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key); diff --git a/src/pk/ecc/ecc_import_openssl.c b/src/pk/ecc/ecc_import_openssl.c index 325b0b05a..9008c73a7 100644 --- a/src/pk/ecc/ecc_import_openssl.c +++ b/src/pk/ecc/ecc_import_openssl.c @@ -9,9 +9,7 @@ static int s_ecc_import_private_with_oid(const unsigned char *in, unsigned long { ltc_asn1_list seq_priv[4], custom[2]; unsigned char bin_xy[2*ECC_MAXSIZE+2], bin_k[ECC_MAXSIZE]; - unsigned long len, pkver = 0, curveoid[16]; - char OID[256]; - const ltc_ecc_curve *curve; + unsigned long pkver = 0, curveoid[16]; int err; /* ### try to load private key - no curve parameters just curve OID */ @@ -26,26 +24,37 @@ static int s_ecc_import_private_with_oid(const unsigned char *in, unsigned long /* try to load private key */ err = der_decode_sequence(in, inlen, seq_priv, 4); - if (err == CRYPT_OK) { - /* load curve parameters for given curve OID */ - len = sizeof(OID); - if ((err = pk_oid_num_to_str(curveoid, custom[0].size, OID, &len)) != CRYPT_OK) { goto error; } - if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; } - if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; } - /* load private+public key */ - err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key); - } + if (err != CRYPT_OK) { goto error; } + err = ecc_import_with_oid(bin_k, seq_priv[1].size, curveoid, custom[0].size, PK_PRIVATE, key); error: return err; } -static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned long inlen, ecc_key *key) +int ecc_import_with_oid(const unsigned char *in, unsigned long inlen, unsigned long *oid, unsigned long oid_len, int type, ecc_key *key) +{ + char OID[256]; + unsigned long len; + const ltc_ecc_curve *curve; + int err; + + /* load curve parameters for given curve OID */ + len = sizeof(OID); + if ((err = pk_oid_num_to_str(oid, oid_len, OID, &len)) != CRYPT_OK) { goto error; } + if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; } + if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; } + /* load public key */ + err = ecc_set_key(in, inlen, type, key); +error: + return err; +} + +int ecc_import_with_curve(const unsigned char *in, unsigned long inlen, int type, ecc_key *key) { void *prime, *order, *a, *b, *gx, *gy; ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], custom[2]; unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE]; unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; - unsigned long len_a, len_b, len_k, len_g; + unsigned long len_a, len_b, len_k, len_g, len_xy, len; unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16]; int err; @@ -53,23 +62,6 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon return err; } - /* ### try to load private key - curve parameters included */ - - /* ECPrivateKey SEQUENCE */ - LTC_SET_ASN1(custom, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); - LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8UL*sizeof(bin_xy)); - LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); - LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k)); - LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */ - LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */ - /* ECParameters SEQUENCE */ - LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); - LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); - LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); - LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g)); - LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); - LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); - seq_ecparams[5].optional = 1; /* FieldID SEQUENCE */ LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); @@ -78,10 +70,33 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, sizeof(bin_b)); LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, 8UL*sizeof(bin_seed)); seq_curve[2].optional = 1; - /* try to load private key */ - err = der_decode_sequence(in, inlen, seq_priv, 4); + /* ECParameters SEQUENCE */ + LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); + LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); + LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); + LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g)); + LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); + LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); + seq_ecparams[5].optional = 1; + if (type == PK_PRIVATE) { + /* ECPrivateKey SEQUENCE */ + LTC_SET_ASN1(custom, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); + LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8UL*sizeof(bin_xy)); + LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); + LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k)); + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */ + /* try to load private key */ + err = der_decode_sequence(in, inlen, seq_priv, 4); + } else if (type == PK_PUBLIC) { + /* try to load public key */ + len_xy = sizeof(bin_xy); + len = 6; + err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len); + } else { + err = CRYPT_PK_INVALID_TYPE; + } if (err == CRYPT_OK) { - len_k = seq_priv[1].size; len_a = seq_curve[0].size; len_b = seq_curve[1].size; len_g = seq_ecparams[3].size; @@ -91,8 +106,15 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } /* load curve parameters */ if ((err = ecc_set_curve_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } - /* load private+public key */ - err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key); + + if (type == PK_PRIVATE) { + len_k = seq_priv[1].size; + /* load private+public key */ + err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key); + } else { + /* load public key */ + err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key); + } } error: mp_clear_multi(prime, order, a, b, gx, gy, LTC_NULL); @@ -111,7 +133,7 @@ int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *ke goto success; } - err = s_ecc_import_private_with_curve(in, inlen, key); + err = ecc_import_with_curve(in, inlen, PK_PRIVATE, key); success: return err; diff --git a/src/pk/ecc/ecc_import_x509.c b/src/pk/ecc/ecc_import_x509.c index e4ba5e3af..5217c8508 100644 --- a/src/pk/ecc/ecc_import_x509.c +++ b/src/pk/ecc/ecc_import_x509.c @@ -8,78 +8,16 @@ static int s_ecc_import_x509_with_oid(const unsigned char *in, unsigned long inl { unsigned char bin_xy[2*ECC_MAXSIZE+2]; unsigned long curveoid[16]; - unsigned long len_xy, len_oid, len; - char OID[256]; - const ltc_ecc_curve *curve; + unsigned long len_xy, len_oid; int err; len_xy = sizeof(bin_xy); len_oid = 16; err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid); - if (err == CRYPT_OK) { - /* load curve parameters for given curve OID */ - len = sizeof(OID); - if ((err = pk_oid_num_to_str(curveoid, len_oid, OID, &len)) != CRYPT_OK) { goto error; } - if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; } - if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; } - /* load public key */ - err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key); - } -error: - return err; -} - -static int s_ecc_import_x509_with_curve(const unsigned char *in, unsigned long inlen, ecc_key *key) -{ - void *prime, *order, *a, *b, *gx, *gy; - ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6]; - unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE]; - unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; - unsigned long len_a, len_b, len_g, len_xy, len; - unsigned long cofactor = 0, ecver = 0, tmpoid[16]; - int err; - - if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, LTC_NULL)) != CRYPT_OK) { - return err; - } - - /* ECParameters SEQUENCE */ - LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); - LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); - LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); - LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g)); - LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); - LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); - seq_ecparams[5].optional = 1; - /* FieldID SEQUENCE */ - LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); - LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); - /* Curve SEQUENCE */ - LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, sizeof(bin_a)); - LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, sizeof(bin_b)); - LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, 8u*sizeof(bin_seed)); - seq_curve[2].optional = 1; - /* try to load public key */ - len_xy = sizeof(bin_xy); - len = 6; - err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len); - - if (err == CRYPT_OK) { - len_a = seq_curve[0].size; - len_b = seq_curve[1].size; - len_g = seq_ecparams[3].size; - /* create bignums */ - if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } - if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } - if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } - /* load curve parameters */ - if ((err = ecc_set_curve_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } - /* load public key */ - err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key); - } + if (err != CRYPT_OK) { goto error; } + err = ecc_import_with_oid(bin_xy, len_xy, curveoid, len_oid, PK_PUBLIC, key); error: - mp_clear_multi(prime, order, a, b, gx, gy, LTC_NULL); return err; } @@ -91,7 +29,7 @@ int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long in goto success; } - err = s_ecc_import_x509_with_curve(in, inlen, key); + err = ecc_import_with_curve(in, inlen, PK_PUBLIC, key); success: return err;