summaryrefslogtreecommitdiff
path: root/src/ltc/pk/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'src/ltc/pk/rsa')
-rw-r--r--src/ltc/pk/rsa/rsa_decrypt_key.c1
-rw-r--r--src/ltc/pk/rsa/rsa_encrypt_key.c2
-rw-r--r--src/ltc/pk/rsa/rsa_export.c2
-rw-r--r--src/ltc/pk/rsa/rsa_import.c116
-rw-r--r--src/ltc/pk/rsa/rsa_import_pkcs8.c31
-rw-r--r--src/ltc/pk/rsa/rsa_import_x509.c2
-rw-r--r--src/ltc/pk/rsa/rsa_key.c4
-rw-r--r--src/ltc/pk/rsa/rsa_make_key.c4
-rw-r--r--src/ltc/pk/rsa/rsa_verify_hash.c2
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) {