Path: blob/master/libs/tomcrypt/src/pk/dsa/dsa_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 dsa_import.c12DSA implementation, import a DSA key, Tom St Denis13*/1415#ifdef LTC_MDSA1617/**18Import a DSA key19@param in The binary packet to import from20@param inlen The length of the binary packet21@param key [out] Where to store the imported key22@return CRYPT_OK if successful, upon error this function will free all allocated memory23*/24int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)25{26int err, stat;27unsigned long zero = 0;28unsigned char* tmpbuf = NULL;29unsigned char flags[1];3031LTC_ARGCHK(in != NULL);32LTC_ARGCHK(key != NULL);33LTC_ARGCHK(ltc_mp.name != NULL);3435/* init key */36if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {37return CRYPT_MEM;38}3940/* try to match the old libtomcrypt format */41err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,42LTC_ASN1_EOL, 0UL, NULL);4344if (err == CRYPT_OK || err == CRYPT_INPUT_TOO_LONG) {45/* private key */46if (flags[0] == 1) {47if ((err = der_decode_sequence_multi(in, inlen,48LTC_ASN1_BIT_STRING, 1UL, flags,49LTC_ASN1_INTEGER, 1UL, key->g,50LTC_ASN1_INTEGER, 1UL, key->p,51LTC_ASN1_INTEGER, 1UL, key->q,52LTC_ASN1_INTEGER, 1UL, key->y,53LTC_ASN1_INTEGER, 1UL, key->x,54LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {55goto LBL_ERR;56}57key->type = PK_PRIVATE;58goto LBL_OK;59}60/* public key */61else if (flags[0] == 0) {62if ((err = der_decode_sequence_multi(in, inlen,63LTC_ASN1_BIT_STRING, 1UL, flags,64LTC_ASN1_INTEGER, 1UL, key->g,65LTC_ASN1_INTEGER, 1UL, key->p,66LTC_ASN1_INTEGER, 1UL, key->q,67LTC_ASN1_INTEGER, 1UL, key->y,68LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {69goto LBL_ERR;70}71key->type = PK_PUBLIC;72goto LBL_OK;73}74else {75err = CRYPT_INVALID_PACKET;76goto LBL_ERR;77}78}79/* get key type */80if ((err = der_decode_sequence_multi(in, inlen,81LTC_ASN1_SHORT_INTEGER, 1UL, &zero,82LTC_ASN1_INTEGER, 1UL, key->p,83LTC_ASN1_INTEGER, 1UL, key->q,84LTC_ASN1_INTEGER, 1UL, key->g,85LTC_ASN1_INTEGER, 1UL, key->y,86LTC_ASN1_INTEGER, 1UL, key->x,87LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {8889key->type = PK_PRIVATE;90} else { /* public */91ltc_asn1_list params[3];92unsigned long tmpbuf_len = inlen;9394LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);95LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);96LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);9798tmpbuf = XCALLOC(1, tmpbuf_len);99if (tmpbuf == NULL) {100err = CRYPT_MEM;101goto LBL_ERR;102}103104err = der_decode_subject_public_key_info(in, inlen, PKA_DSA,105tmpbuf, &tmpbuf_len,106LTC_ASN1_SEQUENCE, params, 3);107if (err != CRYPT_OK) {108XFREE(tmpbuf);109goto LBL_ERR;110}111112if ((err=der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {113XFREE(tmpbuf);114goto LBL_ERR;115}116117XFREE(tmpbuf);118key->type = PK_PUBLIC;119}120121LBL_OK:122key->qord = mp_unsigned_bin_size(key->q);123124/* quick p, q, g validation, without primality testing */125if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK) {126goto LBL_ERR;127}128if (stat == 0) {129err = CRYPT_INVALID_PACKET;130goto LBL_ERR;131}132/* validate x, y */133if ((err = dsa_int_validate_xy(key, &stat)) != CRYPT_OK) {134goto LBL_ERR;135}136if (stat == 0) {137err = CRYPT_INVALID_PACKET;138goto LBL_ERR;139}140141return CRYPT_OK;142LBL_ERR:143dsa_free(key);144return err;145}146147#endif148149150