blob: 31f84a86b477f325a051ae39d4146b0496181b8f [file] [log] [blame]
Juan Castillo11abdcd2014-10-21 11:30:42 +01001/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <stddef.h>
32#include <stdio.h>
33#include <string.h>
34#include <openssl/err.h>
35#include <openssl/x509v3.h>
36#include "ext.h"
37
38DECLARE_ASN1_ITEM(ASN1_INTEGER)
39DECLARE_ASN1_ITEM(ASN1_OCTET_STRING)
40
41/*
42 * This function adds the TBB extensions to the internal extension list
43 * maintained by OpenSSL so they can be used later.
44 *
45 * It also initializes the methods to print the contents of the extension. If an
46 * alias is specified in the TBB extension, we reuse the methods of the alias.
47 * Otherwise, only methods for V_ASN1_INTEGER and V_ASN1_OCTET_STRING are
48 * provided. Any other type will be printed as a raw ascii string.
49 *
50 * Return: 0 = success, Otherwise: error
51 */
52int ext_init(ext_t *tbb_ext)
53{
54 ext_t *ext;
55 X509V3_EXT_METHOD *m;
56 int i = 0, nid, ret;
57
58 while ((ext = &tbb_ext[i++]) && ext->oid) {
59 nid = OBJ_create(ext->oid, ext->sn, ext->ln);
60 if (ext->alias) {
61 X509V3_EXT_add_alias(nid, ext->alias);
62 } else {
63 m = &ext->method;
64 memset(m, 0x0, sizeof(X509V3_EXT_METHOD));
65 switch (ext->type) {
66 case V_ASN1_INTEGER:
67 m->it = ASN1_ITEM_ref(ASN1_INTEGER);
68 m->i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER;
69 m->s2i = (X509V3_EXT_S2I)s2i_ASN1_INTEGER;
70 break;
71 case V_ASN1_OCTET_STRING:
72 m->it = ASN1_ITEM_ref(ASN1_OCTET_STRING);
73 m->i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING;
74 m->s2i = (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING;
75 break;
76 default:
77 continue;
78 }
79 m->ext_nid = nid;
80 ret = X509V3_EXT_add(m);
81 if (!ret) {
82 ERR_print_errors_fp(stdout);
83 return 1;
84 }
85 }
86 }
87 return 0;
88}
89
90/*
91 * Create a new extension
92 *
93 * Extension ::= SEQUENCE {
94 * id OBJECT IDENTIFIER,
95 * critical BOOLEAN DEFAULT FALSE,
96 * value OCTET STRING }
97 *
98 * Parameters:
99 * pex: OpenSSL extension pointer (output parameter)
100 * nid: extension identifier
101 * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
102 * data: extension data. This data will be encapsulated in an Octet String
103 *
104 * Return: Extension address, NULL if error
105 */
106static
107X509_EXTENSION *ext_new(int nid, int crit, unsigned char *data, int len)
108{
109 X509_EXTENSION *ex;
110 ASN1_OCTET_STRING *ext_data;
111
112 /* Octet string containing the extension data */
113 ext_data = ASN1_OCTET_STRING_new();
114 ASN1_OCTET_STRING_set(ext_data, data, len);
115
116 /* Create the extension */
117 ex = X509_EXTENSION_create_by_NID(NULL, nid, crit, ext_data);
118
119 /* The extension makes a copy of the data, so we can free this object */
120 ASN1_OCTET_STRING_free(ext_data);
121
122 return ex;
123}
124
125/*
126 * Creates a x509v3 extension containing a hash encapsulated in an ASN1 Octet
127 * String
128 *
129 * Parameters:
130 * pex: OpenSSL extension pointer (output parameter)
131 * nid: extension identifier
132 * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
133 * buf: pointer to the buffer that contains the hash
134 * len: size of the hash in bytes
135 *
136 * Return: Extension address, NULL if error
137 */
138X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len)
139{
140 X509_EXTENSION *ex = NULL;
141 ASN1_OCTET_STRING *hash = NULL;
142 unsigned char *p = NULL;
143 int sz = -1;
144
145 /* Encode Hash */
146 hash = ASN1_OCTET_STRING_new();
147 ASN1_OCTET_STRING_set(hash, buf, len);
148 sz = i2d_ASN1_OCTET_STRING(hash, NULL);
149 i2d_ASN1_OCTET_STRING(hash, &p);
150
151 /* Create the extension */
152 ex = ext_new(nid, crit, p, sz);
153
154 /* Clean up */
155 OPENSSL_free(p);
156 ASN1_OCTET_STRING_free(hash);
157
158 return ex;
159}
160
161/*
162 * Creates a x509v3 extension containing a nvcounter encapsulated in an ASN1
163 * Integer
164 *
165 * Parameters:
166 * pex: OpenSSL extension pointer (output parameter)
167 * nid: extension identifier
168 * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
169 * value: nvcounter value
170 *
171 * Return: Extension address, NULL if error
172 */
173X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value)
174{
175 X509_EXTENSION *ex = NULL;
176 ASN1_INTEGER *counter = NULL;
177 unsigned char *p = NULL;
178 int sz = -1;
179
180 /* Encode counter */
181 counter = ASN1_INTEGER_new();
182 ASN1_INTEGER_set(counter, value);
183 sz = i2d_ASN1_INTEGER(counter, NULL);
184 i2d_ASN1_INTEGER(counter, &p);
185
186 /* Create the extension */
187 ex = ext_new(nid, crit, p, sz);
188
189 /* Free objects */
190 OPENSSL_free(p);
191 ASN1_INTEGER_free(counter);
192
193 return ex;
194}
195
196/*
197 * Creates a x509v3 extension containing a public key in DER format:
198 *
199 * SubjectPublicKeyInfo ::= SEQUENCE {
200 * algorithm AlgorithmIdentifier,
201 * subjectPublicKey BIT STRING }
202 *
203 * Parameters:
204 * pex: OpenSSL extension pointer (output parameter)
205 * nid: extension identifier
206 * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
207 * k: key
208 *
209 * Return: Extension address, NULL if error
210 */
211X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k)
212{
213 X509_EXTENSION *ex = NULL;
214 unsigned char *p = NULL;
215 int sz = -1;
216
217 /* Encode key */
218 BIO *mem = BIO_new(BIO_s_mem());
219 if (i2d_PUBKEY_bio(mem, k) <= 0) {
220 ERR_print_errors_fp(stderr);
221 return NULL;
222 }
223 p = (unsigned char *)OPENSSL_malloc(4096);
224 sz = BIO_read(mem, p, 4096);
225
226 /* Create the extension */
227 ex = ext_new(nid, crit, p, sz);
228
229 /* Clean up */
230 OPENSSL_free(p);
231
232 return ex;
233}