Path: blob/master/libs/tomcrypt/src/pk/rsa/rsa_import.c
4396 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910/**11@file rsa_import.c12Import a PKCS RSA key, Tom St Denis13*/1415#ifdef LTC_MRSA1617/**18Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1]19@param in The packet to import from20@param inlen It's length (octets)21@param key [out] Destination for newly imported key22@return CRYPT_OK if successful, upon error allocated memory is freed23*/24int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)25{26int err;27void *zero;28unsigned char *tmpbuf=NULL;29unsigned long tmpbuf_len;3031LTC_ARGCHK(in != NULL);32LTC_ARGCHK(key != NULL);33LTC_ARGCHK(ltc_mp.name != NULL);3435/* init key */36if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,37&key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {38return err;39}4041/* see if the OpenSSL DER format RSA public key will work */42tmpbuf_len = inlen;43tmpbuf = XCALLOC(1, tmpbuf_len);44if (tmpbuf == NULL) {45err = CRYPT_MEM;46goto LBL_ERR;47}4849err = der_decode_subject_public_key_info(in, inlen,50PKA_RSA, tmpbuf, &tmpbuf_len,51LTC_ASN1_NULL, NULL, 0);5253if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */5455/* now it should be SEQUENCE { INTEGER, INTEGER } */56if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len,57LTC_ASN1_INTEGER, 1UL, key->N,58LTC_ASN1_INTEGER, 1UL, key->e,59LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {60goto LBL_ERR;61}62key->type = PK_PUBLIC;63err = CRYPT_OK;64goto LBL_FREE;65}6667/* not SSL public key, try to match against PKCS #1 standards */68err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N,69LTC_ASN1_EOL, 0UL, NULL);7071if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {72goto LBL_ERR;73}7475if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) {76if ((err = mp_init(&zero)) != CRYPT_OK) {77goto LBL_ERR;78}79/* it's a private key */80if ((err = der_decode_sequence_multi(in, inlen,81LTC_ASN1_INTEGER, 1UL, zero,82LTC_ASN1_INTEGER, 1UL, key->N,83LTC_ASN1_INTEGER, 1UL, key->e,84LTC_ASN1_INTEGER, 1UL, key->d,85LTC_ASN1_INTEGER, 1UL, key->p,86LTC_ASN1_INTEGER, 1UL, key->q,87LTC_ASN1_INTEGER, 1UL, key->dP,88LTC_ASN1_INTEGER, 1UL, key->dQ,89LTC_ASN1_INTEGER, 1UL, key->qP,90LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {91mp_clear(zero);92goto LBL_ERR;93}94mp_clear(zero);95key->type = PK_PRIVATE;96} else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) {97/* we don't support multi-prime RSA */98err = CRYPT_PK_INVALID_TYPE;99goto LBL_ERR;100} else {101/* it's a public key and we lack e */102if ((err = der_decode_sequence_multi(in, inlen,103LTC_ASN1_INTEGER, 1UL, key->N,104LTC_ASN1_INTEGER, 1UL, key->e,105LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {106goto LBL_ERR;107}108key->type = PK_PUBLIC;109}110err = CRYPT_OK;111goto LBL_FREE;112113LBL_ERR:114mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);115116LBL_FREE:117if (tmpbuf != NULL)118XFREE(tmpbuf);119120return err;121}122123#endif /* LTC_MRSA */124125126