~ubuntu-branches/ubuntu/saucy/wpasupplicant/saucy

« back to all changes in this revision

Viewing changes to src/tls/pkcs8.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-22 09:43:43 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122094343-qgsxaojvmswfri77
Tags: 0.7.3-0ubuntu1
* Get wpasupplicant 0.7.3 from Debian's SVN. Leaving 0.7.3-1 as unreleased
  for now.
* Build-Depend on debhelper 8, since the packaging from Debian uses compat 8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * PKCS #8 (Private-key information syntax)
 
3
 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#include "common.h"
 
18
#include "asn1.h"
 
19
#include "bignum.h"
 
20
#include "rsa.h"
 
21
#include "pkcs5.h"
 
22
#include "pkcs8.h"
 
23
 
 
24
 
 
25
struct crypto_private_key * pkcs8_key_import(const u8 *buf, size_t len)
 
26
{
 
27
        struct asn1_hdr hdr;
 
28
        const u8 *pos, *end;
 
29
        struct bignum *zero;
 
30
        struct asn1_oid oid;
 
31
        char obuf[80];
 
32
 
 
33
        /* PKCS #8, Chapter 6 */
 
34
 
 
35
        /* PrivateKeyInfo ::= SEQUENCE */
 
36
        if (asn1_get_next(buf, len, &hdr) < 0 ||
 
37
            hdr.class != ASN1_CLASS_UNIVERSAL ||
 
38
            hdr.tag != ASN1_TAG_SEQUENCE) {
 
39
                wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
 
40
                           "header (SEQUENCE); assume PKCS #8 not used");
 
41
                return NULL;
 
42
        }
 
43
        pos = hdr.payload;
 
44
        end = pos + hdr.length;
 
45
 
 
46
        /* version Version (Version ::= INTEGER) */
 
47
        if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 
48
            hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
 
49
                wpa_printf(MSG_DEBUG, "PKCS #8: Expected INTEGER - found "
 
50
                           "class %d tag 0x%x; assume PKCS #8 not used",
 
51
                           hdr.class, hdr.tag);
 
52
                return NULL;
 
53
        }
 
54
 
 
55
        zero = bignum_init();
 
56
        if (zero == NULL)
 
57
                return NULL;
 
58
 
 
59
        if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) {
 
60
                wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER");
 
61
                bignum_deinit(zero);
 
62
                return NULL;
 
63
        }
 
64
        pos = hdr.payload + hdr.length;
 
65
 
 
66
        if (bignum_cmp_d(zero, 0) != 0) {
 
67
                wpa_printf(MSG_DEBUG, "PKCS #8: Expected zero INTEGER in the "
 
68
                           "beginning of private key; not found; assume "
 
69
                           "PKCS #8 not used");
 
70
                bignum_deinit(zero);
 
71
                return NULL;
 
72
        }
 
73
        bignum_deinit(zero);
 
74
 
 
75
        /* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
 
76
         * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
 
77
        if (asn1_get_next(pos, len, &hdr) < 0 ||
 
78
            hdr.class != ASN1_CLASS_UNIVERSAL ||
 
79
            hdr.tag != ASN1_TAG_SEQUENCE) {
 
80
                wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
 
81
                           "(AlgorithmIdentifier) - found class %d tag 0x%x; "
 
82
                           "assume PKCS #8 not used",
 
83
                           hdr.class, hdr.tag);
 
84
                return NULL;
 
85
        }
 
86
 
 
87
        if (asn1_get_oid(hdr.payload, hdr.length, &oid, &pos)) {
 
88
                wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse OID "
 
89
                           "(algorithm); assume PKCS #8 not used");
 
90
                return NULL;
 
91
        }
 
92
 
 
93
        asn1_oid_to_str(&oid, obuf, sizeof(obuf));
 
94
        wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf);
 
95
 
 
96
        if (oid.len != 7 ||
 
97
            oid.oid[0] != 1 /* iso */ ||
 
98
            oid.oid[1] != 2 /* member-body */ ||
 
99
            oid.oid[2] != 840 /* us */ ||
 
100
            oid.oid[3] != 113549 /* rsadsi */ ||
 
101
            oid.oid[4] != 1 /* pkcs */ ||
 
102
            oid.oid[5] != 1 /* pkcs-1 */ ||
 
103
            oid.oid[6] != 1 /* rsaEncryption */) {
 
104
                wpa_printf(MSG_DEBUG, "PKCS #8: Unsupported private key "
 
105
                           "algorithm %s", obuf);
 
106
                return NULL;
 
107
        }
 
108
 
 
109
        pos = hdr.payload + hdr.length;
 
110
 
 
111
        /* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
 
112
        if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 
113
            hdr.class != ASN1_CLASS_UNIVERSAL ||
 
114
            hdr.tag != ASN1_TAG_OCTETSTRING) {
 
115
                wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
 
116
                           "(privateKey) - found class %d tag 0x%x",
 
117
                           hdr.class, hdr.tag);
 
118
                return NULL;
 
119
        }
 
120
        wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey");
 
121
 
 
122
        return (struct crypto_private_key *)
 
123
                crypto_rsa_import_private_key(hdr.payload, hdr.length);
 
124
}
 
125
 
 
126
 
 
127
struct crypto_private_key *
 
128
pkcs8_enc_key_import(const u8 *buf, size_t len, const char *passwd)
 
129
{
 
130
        struct asn1_hdr hdr;
 
131
        const u8 *pos, *end, *enc_alg;
 
132
        size_t enc_alg_len;
 
133
        u8 *data;
 
134
        size_t data_len;
 
135
 
 
136
        if (passwd == NULL)
 
137
                return NULL;
 
138
 
 
139
        /*
 
140
         * PKCS #8, Chapter 7
 
141
         * EncryptedPrivateKeyInfo ::= SEQUENCE {
 
142
         *   encryptionAlgorithm EncryptionAlgorithmIdentifier,
 
143
         *   encryptedData EncryptedData }
 
144
         * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
 
145
         * EncryptedData ::= OCTET STRING
 
146
         */
 
147
 
 
148
        if (asn1_get_next(buf, len, &hdr) < 0 ||
 
149
            hdr.class != ASN1_CLASS_UNIVERSAL ||
 
150
            hdr.tag != ASN1_TAG_SEQUENCE) {
 
151
                wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
 
152
                           "header (SEQUENCE); assume encrypted PKCS #8 not "
 
153
                           "used");
 
154
                return NULL;
 
155
        }
 
156
        pos = hdr.payload;
 
157
        end = pos + hdr.length;
 
158
 
 
159
        /* encryptionAlgorithm EncryptionAlgorithmIdentifier */
 
160
        if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 
161
            hdr.class != ASN1_CLASS_UNIVERSAL ||
 
162
            hdr.tag != ASN1_TAG_SEQUENCE) {
 
163
                wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
 
164
                           "(AlgorithmIdentifier) - found class %d tag 0x%x; "
 
165
                           "assume encrypted PKCS #8 not used",
 
166
                           hdr.class, hdr.tag);
 
167
                return NULL;
 
168
        }
 
169
        enc_alg = hdr.payload;
 
170
        enc_alg_len = hdr.length;
 
171
        pos = hdr.payload + hdr.length;
 
172
 
 
173
        /* encryptedData EncryptedData */
 
174
        if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 
175
            hdr.class != ASN1_CLASS_UNIVERSAL ||
 
176
            hdr.tag != ASN1_TAG_OCTETSTRING) {
 
177
                wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
 
178
                           "(encryptedData) - found class %d tag 0x%x",
 
179
                           hdr.class, hdr.tag);
 
180
                return NULL;
 
181
        }
 
182
 
 
183
        data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
 
184
                             passwd, &data_len);
 
185
        if (data) {
 
186
                struct crypto_private_key *key;
 
187
                key = pkcs8_key_import(data, data_len);
 
188
                os_free(data);
 
189
                return key;
 
190
        }
 
191
 
 
192
        return NULL;
 
193
}