diff options
Diffstat (limited to 'libtomcrypt/pk/rsa/rsa_import.c')
-rw-r--r-- | libtomcrypt/pk/rsa/rsa_import.c | 196 |
1 files changed, 102 insertions, 94 deletions
diff --git a/libtomcrypt/pk/rsa/rsa_import.c b/libtomcrypt/pk/rsa/rsa_import.c index 87cb103..de8a103 100644 --- a/libtomcrypt/pk/rsa/rsa_import.c +++ b/libtomcrypt/pk/rsa/rsa_import.c @@ -10,11 +10,10 @@ */ #include "tomcrypt.h" - /** @file rsa_import.c Import a LTC_PKCS RSA key, Tom St Denis -*/ +*/ #ifdef LTC_MRSA @@ -25,104 +24,113 @@ @param key [out] Destination for newly imported key @return CRYPT_OK if successful, upon error allocated memory is freed */ -int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key * key) { - int err; - mp_int zero; - unsigned char *tmpbuf=NULL; - unsigned long tmpbuf_len; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(key != NULL); - - /* init key */ - if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { - return err; - } - - /* see if the OpenSSL DER format RSA public key will work */ - tmpbuf_len = MAX_RSA_SIZE * 8; - tmpbuf = XCALLOC(1, tmpbuf_len); - if (tmpbuf == NULL) { - err = CRYPT_MEM; - goto LBL_ERR; - } - - err = der_decode_subject_public_key_info(in, inlen, - PKA_RSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_NULL, NULL, 0); - - if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ - - /* now it should be SEQUENCE { INTEGER, INTEGER } */ - if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_INTEGER, 1UL, &key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - - XFREE(tmpbuf); - - key->type = PK_PUBLIC; - return CRYPT_OK; - } - - XFREE(tmpbuf); - - /* not SSL public key, try to match against LTC_PKCS #1 standards */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - 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; - } - return CRYPT_OK; + int err; + mp_int zero; + unsigned char *tmpbuf = NULL; + unsigned long tmpbuf_len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + /* init key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, + NULL)) != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf_len = MAX_RSA_SIZE * 8; + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + err = der_decode_subject_public_key_info(in, inlen, + PKA_RSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_NULL, NULL, 0); + + if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ + + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, + LTC_ASN1_INTEGER, 1UL, + &key->N, LTC_ASN1_INTEGER, + 1UL, &key->e, LTC_ASN1_EOL, + 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + XFREE(tmpbuf); + + key->type = PK_PUBLIC; + return CRYPT_OK; + } + + XFREE(tmpbuf); + + /* not SSL public key, try to match against LTC_PKCS #1 standards */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_EOL, 0UL, + NULL)) != CRYPT_OK) { + 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; + } + return CRYPT_OK; LBL_ERR: - XFREE(tmpbuf); - mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); - return err; + XFREE(tmpbuf); + mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, + &key->p, &key->q, NULL); + return err; } #endif /* LTC_MRSA */ - /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ /* $Revision: 1.23 $ */ /* $Date: 2007/05/12 14:32:35 $ */ |