]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/dsa/dsa_import.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / dsa / dsa_import.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include "tomcrypt.h"
10
11 /**
12    @file dsa_import.c
13    DSA implementation, import a DSA key, Tom St Denis
14 */
15
16 #ifdef LTC_MDSA
17
18 /**
19    Import a DSA key
20    @param in       The binary packet to import from
21    @param inlen    The length of the binary packet
22    @param key      [out] Where to store the imported key
23    @return CRYPT_OK if successful, upon error this function will free all allocated memory
24 */
25 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
26 {
27    int           err, stat;
28    unsigned long zero = 0;
29    unsigned char* tmpbuf = NULL;
30    unsigned char flags[1];
31
32    LTC_ARGCHK(in  != NULL);
33    LTC_ARGCHK(key != NULL);
34    LTC_ARGCHK(ltc_mp.name != NULL);
35
36    /* init key */
37    if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {
38       return CRYPT_MEM;
39    }
40
41    /* try to match the old libtomcrypt format */
42    err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,
43                                               LTC_ASN1_EOL,        0UL, NULL);
44
45    if (err == CRYPT_OK || err == CRYPT_INPUT_TOO_LONG) {
46        /* private key */
47        if (flags[0] == 1) {
48            if ((err = der_decode_sequence_multi(in, inlen,
49                                   LTC_ASN1_BIT_STRING,   1UL, flags,
50                                   LTC_ASN1_INTEGER,      1UL, key->g,
51                                   LTC_ASN1_INTEGER,      1UL, key->p,
52                                   LTC_ASN1_INTEGER,      1UL, key->q,
53                                   LTC_ASN1_INTEGER,      1UL, key->y,
54                                   LTC_ASN1_INTEGER,      1UL, key->x,
55                                   LTC_ASN1_EOL,          0UL, NULL)) != CRYPT_OK) {
56                goto LBL_ERR;
57            }
58            key->type = PK_PRIVATE;
59            goto LBL_OK;
60        }
61        /* public key */
62        else if (flags[0] == 0) {
63            if ((err = der_decode_sequence_multi(in, inlen,
64                                       LTC_ASN1_BIT_STRING,   1UL, flags,
65                                       LTC_ASN1_INTEGER,      1UL, key->g,
66                                       LTC_ASN1_INTEGER,      1UL, key->p,
67                                       LTC_ASN1_INTEGER,      1UL, key->q,
68                                       LTC_ASN1_INTEGER,      1UL, key->y,
69                                       LTC_ASN1_EOL,          0UL, NULL)) != CRYPT_OK) {
70                goto LBL_ERR;
71            }
72            key->type = PK_PUBLIC;
73            goto LBL_OK;
74        }
75        else {
76           err = CRYPT_INVALID_PACKET;
77           goto LBL_ERR;
78        }
79    }
80    /* get key type */
81    if ((err = der_decode_sequence_multi(in, inlen,
82                           LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
83                           LTC_ASN1_INTEGER,      1UL, key->p,
84                           LTC_ASN1_INTEGER,      1UL, key->q,
85                           LTC_ASN1_INTEGER,      1UL, key->g,
86                           LTC_ASN1_INTEGER,      1UL, key->y,
87                           LTC_ASN1_INTEGER,      1UL, key->x,
88                           LTC_ASN1_EOL,          0UL, NULL)) == CRYPT_OK) {
89
90        key->type = PK_PRIVATE;
91    } else { /* public */
92       ltc_asn1_list params[3];
93       unsigned long tmpbuf_len = inlen;
94
95       LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
96       LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
97       LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
98
99       tmpbuf = XCALLOC(1, tmpbuf_len);
100       if (tmpbuf == NULL) {
101          err = CRYPT_MEM;
102          goto LBL_ERR;
103       }
104
105       err = der_decode_subject_public_key_info(in, inlen, PKA_DSA,
106                                                tmpbuf, &tmpbuf_len,
107                                                LTC_ASN1_SEQUENCE, params, 3);
108       if (err != CRYPT_OK) {
109          XFREE(tmpbuf);
110          goto LBL_ERR;
111       }
112
113       if ((err=der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
114          XFREE(tmpbuf);
115          goto LBL_ERR;
116       }
117
118       XFREE(tmpbuf);
119       key->type = PK_PUBLIC;
120    }
121
122 LBL_OK:
123    key->qord = mp_unsigned_bin_size(key->q);
124
125    /* quick p, q, g validation, without primality testing */
126    if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK) {
127       goto LBL_ERR;
128    }
129    if (stat == 0) {
130       err = CRYPT_INVALID_PACKET;
131       goto LBL_ERR;
132    }
133    /* validate x, y */
134    if ((err = dsa_int_validate_xy(key, &stat)) != CRYPT_OK) {
135       goto LBL_ERR;
136    }
137    if (stat == 0) {
138       err = CRYPT_INVALID_PACKET;
139       goto LBL_ERR;
140    }
141
142   return CRYPT_OK;
143 LBL_ERR:
144    dsa_free(key);
145    return err;
146 }
147
148 #endif
149
150 /* ref:         $Format:%D$ */
151 /* git commit:  $Format:%H$ */
152 /* commit time: $Format:%ai$ */