comparison libtomcrypt/src/pk/rsa/rsa_import.c @ 382:0cbe8f6dbf9e

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f) to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author Matt Johnston <matt@ucc.asn.au>
date Thu, 11 Jan 2007 02:41:05 +0000
parents 1b9e69c058d2
children f849a5ca2efc
comparison
equal deleted inserted replaced
379:b66a00272a90 382:0cbe8f6dbf9e
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 * 8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org 9 * Tom St Denis, [email protected], http://libtomcrypt.com
10 */ 10 */
11 #include "tomcrypt.h" 11 #include "tomcrypt.h"
12 12
13 /** 13 /**
14 @file rsa_import.c 14 @file rsa_import.c
25 @return CRYPT_OK if successful, upon error allocated memory is freed 25 @return CRYPT_OK if successful, upon error allocated memory is freed
26 */ 26 */
27 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) 27 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
28 { 28 {
29 int err; 29 int err;
30 mp_int zero; 30 void *zero;
31 unsigned char *tmpbuf;
32 unsigned long t, x, y, z, tmpoid[16];
33 ltc_asn1_list ssl_pubkey_hashoid[2];
34 ltc_asn1_list ssl_pubkey[2];
31 35
32 LTC_ARGCHK(in != NULL); 36 LTC_ARGCHK(in != NULL);
33 LTC_ARGCHK(key != NULL); 37 LTC_ARGCHK(key != NULL);
38 LTC_ARGCHK(ltc_mp.name != NULL);
34 39
35 /* init key */ 40 /* init key */
36 if ((err = mp_init_multi(&zero, &key->e, &key->d, &key->N, &key->dQ, 41 if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ,
37 &key->dP, &key->qP, &key->p, &key->q, NULL)) != MP_OKAY) { 42 &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
38 return mpi_to_ltc_error(err); 43 return err;
39 } 44 }
40 45
46 /* see if the OpenSSL DER format RSA public key will work */
47 tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8);
48 if (tmpbuf == NULL) {
49 err = CRYPT_MEM;
50 goto LBL_ERR;
51 }
52
53 /* this includes the internal hash ID and optional params (NULL in this case) */
54 LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
55 LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0);
56
57 /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it
58 then proceed to convert bit to octet
59 */
60 LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2);
61 LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
62
63 if (der_decode_sequence(in, inlen,
64 ssl_pubkey, 2UL) == CRYPT_OK) {
65
66 /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */
67 for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) {
68 y = (y << 1) | tmpbuf[x];
69 if (++z == 8) {
70 tmpbuf[t++] = (unsigned char)y;
71 y = 0;
72 z = 0;
73 }
74 }
75
76 /* now it should be SEQUENCE { INTEGER, INTEGER } */
77 if ((err = der_decode_sequence_multi(tmpbuf, t,
78 LTC_ASN1_INTEGER, 1UL, key->N,
79 LTC_ASN1_INTEGER, 1UL, key->e,
80 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
81 XFREE(tmpbuf);
82 goto LBL_ERR;
83 }
84 XFREE(tmpbuf);
85 key->type = PK_PUBLIC;
86 return CRYPT_OK;
87 }
88 XFREE(tmpbuf);
89
90 /* not SSL public key, try to match against PKCS #1 standards */
41 if ((err = der_decode_sequence_multi(in, inlen, 91 if ((err = der_decode_sequence_multi(in, inlen,
42 LTC_ASN1_INTEGER, 1UL, &key->N, 92 LTC_ASN1_INTEGER, 1UL, key->N,
43 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { 93 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
44 goto LBL_ERR; 94 goto LBL_ERR;
45 } 95 }
46 96
47 if (mp_cmp_d(&key->N, 0) == MP_EQ) { 97 if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) {
98 if ((err = mp_init(&zero)) != CRYPT_OK) {
99 goto LBL_ERR;
100 }
48 /* it's a private key */ 101 /* it's a private key */
49 if ((err = der_decode_sequence_multi(in, inlen, 102 if ((err = der_decode_sequence_multi(in, inlen,
50 LTC_ASN1_INTEGER, 1UL, &zero, 103 LTC_ASN1_INTEGER, 1UL, zero,
51 LTC_ASN1_INTEGER, 1UL, &key->N, 104 LTC_ASN1_INTEGER, 1UL, key->N,
52 LTC_ASN1_INTEGER, 1UL, &key->e, 105 LTC_ASN1_INTEGER, 1UL, key->e,
53 LTC_ASN1_INTEGER, 1UL, &key->d, 106 LTC_ASN1_INTEGER, 1UL, key->d,
54 LTC_ASN1_INTEGER, 1UL, &key->p, 107 LTC_ASN1_INTEGER, 1UL, key->p,
55 LTC_ASN1_INTEGER, 1UL, &key->q, 108 LTC_ASN1_INTEGER, 1UL, key->q,
56 LTC_ASN1_INTEGER, 1UL, &key->dP, 109 LTC_ASN1_INTEGER, 1UL, key->dP,
57 LTC_ASN1_INTEGER, 1UL, &key->dQ, 110 LTC_ASN1_INTEGER, 1UL, key->dQ,
58 LTC_ASN1_INTEGER, 1UL, &key->qP, 111 LTC_ASN1_INTEGER, 1UL, key->qP,
59 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { 112 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
113 mp_clear(zero);
60 goto LBL_ERR; 114 goto LBL_ERR;
61 } 115 }
116 mp_clear(zero);
62 key->type = PK_PRIVATE; 117 key->type = PK_PRIVATE;
63 } else if (mp_cmp_d(&key->N, 1) == MP_EQ) { 118 } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) {
64 /* we don't support multi-prime RSA */ 119 /* we don't support multi-prime RSA */
65 err = CRYPT_PK_INVALID_TYPE; 120 err = CRYPT_PK_INVALID_TYPE;
66 goto LBL_ERR; 121 goto LBL_ERR;
67 } else { 122 } else {
68 /* it's a public key and we lack e */ 123 /* it's a public key and we lack e */
69 if ((err = der_decode_sequence_multi(in, inlen, 124 if ((err = der_decode_sequence_multi(in, inlen,
70 LTC_ASN1_INTEGER, 1UL, &key->N, 125 LTC_ASN1_INTEGER, 1UL, key->N,
71 LTC_ASN1_INTEGER, 1UL, &key->e, 126 LTC_ASN1_INTEGER, 1UL, key->e,
72 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { 127 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
73 goto LBL_ERR; 128 goto LBL_ERR;
74 } 129 }
75
76 /* free up some ram */
77 mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL);
78 key->type = PK_PUBLIC; 130 key->type = PK_PUBLIC;
79 } 131 }
80 return CRYPT_OK; 132 return CRYPT_OK;
81 LBL_ERR: 133 LBL_ERR:
82 mp_clear_multi(&zero, &key->d, &key->e, &key->N, &key->dQ, &key->dP, 134 mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
83 &key->qP, &key->p, &key->q, NULL);
84 return err; 135 return err;
85 } 136 }
86 137
87 #endif /* MRSA */ 138 #endif /* MRSA */
88 139
89 140
90 /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ 141 /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */
91 /* $Revision: 1.10 $ */ 142 /* $Revision: 1.21 $ */
92 /* $Date: 2005/06/03 18:48:28 $ */ 143 /* $Date: 2006/12/04 22:23:27 $ */