]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / asn1 / der / sequence / der_decode_subject_public_key_info.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   @file der_decode_subject_public_key_info.c
12   ASN.1 DER, encode a Subject Public Key structure --nmav
13 */
14
15 #ifdef LTC_DER
16
17 /* AlgorithmIdentifier := SEQUENCE {
18  *    algorithm OBJECT IDENTIFIER,
19  *    parameters ANY DEFINED BY algorithm
20  * }
21  *
22  * SubjectPublicKeyInfo := SEQUENCE {
23  *    algorithm AlgorithmIdentifier,
24  *    subjectPublicKey BIT STRING
25  * }
26  */
27 /**
28   Decode a subject public key info
29    @param in      The input buffer
30    @param inlen   The length of the input buffer
31    @param algorithm             One out of the enum #public_key_algorithms
32    @param public_key            The buffer for the public key
33    @param public_key_len        [in/out] The length of the public key buffer and the written length
34    @param parameters_type       The parameters' type out of the enum ltc_asn1_type
35    @param parameters            The parameters to include
36    @param parameters_len        The number of parameters to include
37    @return CRYPT_OK on success
38 */
39 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
40         unsigned int algorithm, void* public_key, unsigned long* public_key_len,
41         unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len)
42 {
43    int err;
44    unsigned long len;
45    oid_st oid;
46    unsigned char *tmpbuf;
47    unsigned long  tmpoid[16];
48    ltc_asn1_list alg_id[2];
49    ltc_asn1_list subject_pubkey[2];
50
51    LTC_ARGCHK(in    != NULL);
52    LTC_ARGCHK(inlen != 0);
53    LTC_ARGCHK(public_key_len != NULL);
54
55    err = pk_get_oid(algorithm, &oid);
56    if (err != CRYPT_OK) {
57         return err;
58    }
59
60    /* see if the OpenSSL DER format RSA public key will work */
61    tmpbuf = XCALLOC(1, inlen);
62    if (tmpbuf == NULL) {
63        err = CRYPT_MEM;
64        goto LBL_ERR;
65    }
66
67    /* this includes the internal hash ID and optional params (NULL in this case) */
68    LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
69    LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len);
70
71    /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey
72     * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet
73     */
74    LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2);
75    LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U);
76
77    err=der_decode_sequence(in, inlen, subject_pubkey, 2UL);
78    if (err != CRYPT_OK) {
79            goto LBL_ERR;
80    }
81
82    if ((alg_id[0].size != oid.OIDlen) ||
83         XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0])) != 0) {
84         /* OID mismatch */
85         err = CRYPT_PK_INVALID_TYPE;
86         goto LBL_ERR;
87    }
88
89    len = subject_pubkey[1].size/8;
90    if (*public_key_len > len) {
91        XMEMCPY(public_key, subject_pubkey[1].data, len);
92        *public_key_len = len;
93     } else {
94         *public_key_len = len;
95         err = CRYPT_BUFFER_OVERFLOW;
96         goto LBL_ERR;
97     }
98
99     err = CRYPT_OK;
100
101 LBL_ERR:
102
103     XFREE(tmpbuf);
104
105     return err;
106 }
107
108 #endif
109
110 /* ref:         $Format:%D$ */
111 /* git commit:  $Format:%H$ */
112 /* commit time: $Format:%ai$ */