diff options
Diffstat (limited to 'src/ltc/pk/rsa')
-rw-r--r-- | src/ltc/pk/rsa/rsa_decrypt_key.c | 1 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_encrypt_key.c | 2 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_export.c | 2 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_import.c | 116 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_import_pkcs8.c | 31 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_import_x509.c | 2 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_key.c | 4 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_make_key.c | 4 | ||||
-rw-r--r-- | src/ltc/pk/rsa/rsa_verify_hash.c | 2 |
9 files changed, 88 insertions, 76 deletions
diff --git a/src/ltc/pk/rsa/rsa_decrypt_key.c b/src/ltc/pk/rsa/rsa_decrypt_key.c index 34a11f91..8c6ca3d8 100644 --- a/src/ltc/pk/rsa/rsa_decrypt_key.c +++ b/src/ltc/pk/rsa/rsa_decrypt_key.c @@ -33,6 +33,7 @@ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen int err; unsigned char *tmp; + LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); diff --git a/src/ltc/pk/rsa/rsa_encrypt_key.c b/src/ltc/pk/rsa/rsa_encrypt_key.c index 66942608..e0f91e19 100644 --- a/src/ltc/pk/rsa/rsa_encrypt_key.c +++ b/src/ltc/pk/rsa/rsa_encrypt_key.c @@ -34,7 +34,7 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned long modulus_bitlen, modulus_bytelen, x; int err; - LTC_ARGCHK(in != NULL); + LTC_ARGCHK((inlen == 0) || (in != NULL)); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); diff --git a/src/ltc/pk/rsa/rsa_export.c b/src/ltc/pk/rsa/rsa_export.c index ac8fed22..225224d0 100644 --- a/src/ltc/pk/rsa/rsa_export.c +++ b/src/ltc/pk/rsa/rsa_export.c @@ -78,7 +78,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, const rsa_ke } err = x509_encode_subject_public_key_info(out, outlen, - PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0); + LTC_OID_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0); finish: if (tmp != out) XFREE(tmp); diff --git a/src/ltc/pk/rsa/rsa_import.c b/src/ltc/pk/rsa/rsa_import.c index 5efb125e..1240a77e 100644 --- a/src/ltc/pk/rsa/rsa_import.c +++ b/src/ltc/pk/rsa/rsa_import.c @@ -9,8 +9,74 @@ #ifdef LTC_MRSA + +/** + Import an RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only] + + The `key` passed into this function has to be already initialized and will + NOT be free'd on error! + + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful +*/ +int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + unsigned long version = -1; + + err = der_decode_sequence_multi(in, inlen, LTC_ASN1_SHORT_INTEGER, 1UL, &version, + LTC_ASN1_EOL, 0UL, NULL); + + if (err == CRYPT_OVERFLOW) { + /* the version would fit into an LTC_ASN1_SHORT_INTEGER + * so we try to decode as a public key + */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { + key->type = PK_PUBLIC; + } + goto LBL_OUT; + } else if (err != CRYPT_INPUT_TOO_LONG) { + /* couldn't decode the version, so error out */ + goto LBL_OUT; + } + + if (version == 0) { + /* it's a private key */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &version, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_OUT; + } + key->type = PK_PRIVATE; + } else if (version == 1) { + /* we don't support multi-prime RSA */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_OUT; + } + err = CRYPT_OK; +LBL_OUT: + return err; +} + /** - Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1] + Import multiple formats of RSA public and private keys. + + RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only] + SubjectPublicKeyInfo formatted public keys + @param in The packet to import from @param inlen It's length (octets) @param key [out] Destination for newly imported key @@ -19,7 +85,6 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { int err; - void *zero; unsigned char *tmpbuf=NULL; unsigned long tmpbuf_len, len; @@ -42,7 +107,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) len = 0; err = x509_decode_subject_public_key_info(in, inlen, - PKA_RSA, tmpbuf, &tmpbuf_len, + LTC_OID_RSA, tmpbuf, &tmpbuf_len, LTC_ASN1_NULL, NULL, &len); if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ @@ -60,50 +125,9 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) } /* not SSL public key, try to match against PKCS #1 standards */ - err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_EOL, 0UL, NULL); - - if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { - goto LBL_ERR; - } - - if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { - if ((err = mp_init(&zero)) != CRYPT_OK) { - goto LBL_ERR; - } - /* it's a private key */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, zero, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_INTEGER, 1UL, key->d, - LTC_ASN1_INTEGER, 1UL, key->p, - LTC_ASN1_INTEGER, 1UL, key->q, - LTC_ASN1_INTEGER, 1UL, key->dP, - LTC_ASN1_INTEGER, 1UL, key->dQ, - LTC_ASN1_INTEGER, 1UL, key->qP, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - mp_clear(zero); - goto LBL_ERR; - } - mp_clear(zero); - key->type = PK_PRIVATE; - } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) { - /* we don't support multi-prime RSA */ - err = CRYPT_PK_INVALID_TYPE; - goto LBL_ERR; - } else { - /* it's a public key and we lack e */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - key->type = PK_PUBLIC; + if ((err = rsa_import_pkcs1(in, inlen, key)) == CRYPT_OK) { + goto LBL_FREE; } - err = CRYPT_OK; - goto LBL_FREE; LBL_ERR: rsa_free(key); diff --git a/src/ltc/pk/rsa/rsa_import_pkcs8.c b/src/ltc/pk/rsa/rsa_import_pkcs8.c index 5d0bb6d2..9e02585c 100644 --- a/src/ltc/pk/rsa/rsa_import_pkcs8.c +++ b/src/ltc/pk/rsa/rsa_import_pkcs8.c @@ -46,10 +46,9 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, rsa_key *key) { int err; - void *zero, *iter; unsigned char *buf1 = NULL, *buf2 = NULL; unsigned long buf1len, buf2len; - unsigned long oid[16]; + unsigned long oid[16], version; const char *rsaoid; ltc_asn1_list alg_seq[2], top_seq[3]; ltc_asn1_list *l = NULL; @@ -61,7 +60,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, LTC_ARGCHK(ltc_mp.name != NULL); /* get RSA alg oid */ - err = pk_get_oid(PKA_RSA, &rsaoid); + err = pk_get_oid(LTC_OID_RSA, &rsaoid); if (err != CRYPT_OK) { goto LBL_NOFREE; } /* alloc buffers */ @@ -72,9 +71,8 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, buf2 = XMALLOC(buf2len); if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE1; } - if ((err = mp_init_multi(&zero, &iter, NULL)) != CRYPT_OK) { goto LBL_FREE2; } /* init key */ - if ((err = rsa_init(key)) != CRYPT_OK) { goto LBL_FREE3; } + if ((err = rsa_init(key)) != CRYPT_OK) { goto LBL_FREE2; } /* try to decode encrypted priv key */ if ((err = pkcs8_decode_flexi(in, inlen, passwd, passwdlen, &l)) != CRYPT_OK) { @@ -86,7 +84,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, /* try to decode unencrypted priv key */ LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_NULL, NULL, 0UL); - LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL); + LTC_SET_ASN1(top_seq, 0, LTC_ASN1_SHORT_INTEGER, &version, 1UL); LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL); LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len); err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL); @@ -97,28 +95,17 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, goto LBL_ERR; } - err = der_decode_sequence_multi(buf1, top_seq[2].size, - LTC_ASN1_INTEGER, 1UL, zero, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_INTEGER, 1UL, key->d, - LTC_ASN1_INTEGER, 1UL, key->p, - LTC_ASN1_INTEGER, 1UL, key->q, - LTC_ASN1_INTEGER, 1UL, key->dP, - LTC_ASN1_INTEGER, 1UL, key->dQ, - LTC_ASN1_INTEGER, 1UL, key->qP, - LTC_ASN1_EOL, 0UL, NULL); - if (err != CRYPT_OK) { goto LBL_ERR; } + if ((err = rsa_import_pkcs1(buf1, top_seq[2].size, key)) != CRYPT_OK) { + goto LBL_ERR; + } key->type = PK_PRIVATE; err = CRYPT_OK; - goto LBL_FREE3; + goto LBL_FREE2; LBL_ERR: rsa_free(key); -LBL_FREE3: - mp_clear_multi(iter, zero, NULL); - if (l) der_free_sequence_flexi(l); LBL_FREE2: + if (l) der_free_sequence_flexi(l); XFREE(buf2); LBL_FREE1: XFREE(buf1); diff --git a/src/ltc/pk/rsa/rsa_import_x509.c b/src/ltc/pk/rsa/rsa_import_x509.c index a66a2672..e921aae0 100644 --- a/src/ltc/pk/rsa/rsa_import_x509.c +++ b/src/ltc/pk/rsa/rsa_import_x509.c @@ -39,7 +39,7 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) } if ((err = x509_decode_public_key_from_certificate(in, inlen, - PKA_RSA, LTC_ASN1_NULL, + LTC_OID_RSA, LTC_ASN1_NULL, NULL, NULL, (public_key_decode_cb)s_rsa_decode, key)) != CRYPT_OK) { rsa_free(key); diff --git a/src/ltc/pk/rsa/rsa_key.c b/src/ltc/pk/rsa/rsa_key.c index 48a1d8fd..2d0712f2 100644 --- a/src/ltc/pk/rsa/rsa_key.c +++ b/src/ltc/pk/rsa/rsa_key.c @@ -87,7 +87,7 @@ void rsa_shrink_key(rsa_key *key) int rsa_init(rsa_key *key) { LTC_ARGCHK(key != NULL); - return mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); + return mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, LTC_NULL); } /** @@ -97,7 +97,7 @@ int rsa_init(rsa_key *key) void rsa_free(rsa_key *key) { LTC_ARGCHKVD(key != NULL); - mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, NULL); + mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, LTC_NULL); } #endif diff --git a/src/ltc/pk/rsa/rsa_make_key.c b/src/ltc/pk/rsa/rsa_make_key.c index e0402afd..6bfc0419 100644 --- a/src/ltc/pk/rsa/rsa_make_key.c +++ b/src/ltc/pk/rsa/rsa_make_key.c @@ -22,7 +22,7 @@ static int s_rsa_make_key(prng_state *prng, int wprng, int size, void *e, rsa_ke return err; } - if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, NULL)) != CRYPT_OK) { + if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, LTC_NULL)) != CRYPT_OK) { return err; } @@ -76,7 +76,7 @@ static int s_rsa_make_key(prng_state *prng, int wprng, int size, void *e, rsa_ke errkey: rsa_free(key); cleanup: - mp_clear_multi(tmp2, tmp1, q, p, NULL); + mp_clear_multi(tmp2, tmp1, q, p, LTC_NULL); return err; } diff --git a/src/ltc/pk/rsa/rsa_verify_hash.c b/src/ltc/pk/rsa/rsa_verify_hash.c index ca4cdf9c..d946a202 100644 --- a/src/ltc/pk/rsa/rsa_verify_hash.c +++ b/src/ltc/pk/rsa/rsa_verify_hash.c @@ -136,7 +136,7 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); - if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { + if (der_decode_sequence_strict(out, outlen, siginfo, 2) != CRYPT_OK) { /* fallback to Legacy:missing NULL */ LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1); if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { |