2
2
*
3
3
* Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved.
4
4
* Copyright © 2015 Intel Corporation.
5
+ * Copyright © 2016 Hewlett Packard Enterprise Development LP
5
6
*
6
7
* Authors: David Howells <[email protected] >
7
8
* David Woodhouse <[email protected] >
9
+ * Juerg Haefliger <[email protected] >
8
10
*
9
11
* This program is free software; you can redistribute it and/or
10
12
* modify it under the terms of the GNU Lesser General Public License
@@ -67,6 +69,8 @@ void format(void)
67
69
{
68
70
fprintf (stderr ,
69
71
"Usage: scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>]\n" );
72
+ fprintf (stderr ,
73
+ " scripts/sign-file -s <raw sig> <hash algo> <x509> <module> [<dest>]\n" );
70
74
exit (2 );
71
75
}
72
76
@@ -126,26 +130,84 @@ static int pem_pw_cb(char *buf, int len, int w, void *v)
126
130
return pwlen ;
127
131
}
128
132
133
+ static EVP_PKEY * read_private_key (const char * private_key_name )
134
+ {
135
+ EVP_PKEY * private_key ;
136
+
137
+ if (!strncmp (private_key_name , "pkcs11:" , 7 )) {
138
+ ENGINE * e ;
139
+
140
+ ENGINE_load_builtin_engines ();
141
+ drain_openssl_errors ();
142
+ e = ENGINE_by_id ("pkcs11" );
143
+ ERR (!e , "Load PKCS#11 ENGINE" );
144
+ if (ENGINE_init (e ))
145
+ drain_openssl_errors ();
146
+ else
147
+ ERR (1 , "ENGINE_init" );
148
+ if (key_pass )
149
+ ERR (!ENGINE_ctrl_cmd_string (e , "PIN" , key_pass , 0 ),
150
+ "Set PKCS#11 PIN" );
151
+ private_key = ENGINE_load_private_key (e , private_key_name ,
152
+ NULL , NULL );
153
+ ERR (!private_key , "%s" , private_key_name );
154
+ } else {
155
+ BIO * b ;
156
+
157
+ b = BIO_new_file (private_key_name , "rb" );
158
+ ERR (!b , "%s" , private_key_name );
159
+ private_key = PEM_read_bio_PrivateKey (b , NULL , pem_pw_cb ,
160
+ NULL );
161
+ ERR (!private_key , "%s" , private_key_name );
162
+ BIO_free (b );
163
+ }
164
+
165
+ return private_key ;
166
+ }
167
+
168
+ static X509 * read_x509 (const char * x509_name )
169
+ {
170
+ X509 * x509 ;
171
+ BIO * b ;
172
+
173
+ b = BIO_new_file (x509_name , "rb" );
174
+ ERR (!b , "%s" , x509_name );
175
+ x509 = d2i_X509_bio (b , NULL ); /* Binary encoded X.509 */
176
+ if (!x509 ) {
177
+ ERR (BIO_reset (b ) != 1 , "%s" , x509_name );
178
+ x509 = PEM_read_bio_X509 (b , NULL , NULL ,
179
+ NULL ); /* PEM encoded X.509 */
180
+ if (x509 )
181
+ drain_openssl_errors ();
182
+ }
183
+ BIO_free (b );
184
+ ERR (!x509 , "%s" , x509_name );
185
+
186
+ return x509 ;
187
+ }
188
+
129
189
int main (int argc , char * * argv )
130
190
{
131
191
struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 };
132
192
char * hash_algo = NULL ;
133
- char * private_key_name , * x509_name , * module_name , * dest_name ;
193
+ char * private_key_name = NULL , * raw_sig_name = NULL ;
194
+ char * x509_name , * module_name , * dest_name ;
134
195
bool save_sig = false, replace_orig ;
135
196
bool sign_only = false;
197
+ bool raw_sig = false;
136
198
unsigned char buf [4096 ];
137
199
unsigned long module_size , sig_size ;
138
200
unsigned int use_signed_attrs ;
139
201
const EVP_MD * digest_algo ;
140
202
EVP_PKEY * private_key ;
141
203
#ifndef USE_PKCS7
142
- CMS_ContentInfo * cms ;
204
+ CMS_ContentInfo * cms = NULL ;
143
205
unsigned int use_keyid = 0 ;
144
206
#else
145
- PKCS7 * pkcs7 ;
207
+ PKCS7 * pkcs7 = NULL ;
146
208
#endif
147
209
X509 * x509 ;
148
- BIO * b , * bd = NULL , * bm ;
210
+ BIO * bd , * bm ;
149
211
int opt , n ;
150
212
OpenSSL_add_all_algorithms ();
151
213
ERR_load_crypto_strings ();
@@ -160,8 +222,9 @@ int main(int argc, char **argv)
160
222
#endif
161
223
162
224
do {
163
- opt = getopt (argc , argv , "dpk " );
225
+ opt = getopt (argc , argv , "sdpk " );
164
226
switch (opt ) {
227
+ case 's' : raw_sig = true; break ;
165
228
case 'p' : save_sig = true; break ;
166
229
case 'd' : sign_only = true; save_sig = true; break ;
167
230
#ifndef USE_PKCS7
@@ -177,8 +240,13 @@ int main(int argc, char **argv)
177
240
if (argc < 4 || argc > 5 )
178
241
format ();
179
242
180
- hash_algo = argv [0 ];
181
- private_key_name = argv [1 ];
243
+ if (raw_sig ) {
244
+ raw_sig_name = argv [0 ];
245
+ hash_algo = argv [1 ];
246
+ } else {
247
+ hash_algo = argv [0 ];
248
+ private_key_name = argv [1 ];
249
+ }
182
250
x509_name = argv [2 ];
183
251
module_name = argv [3 ];
184
252
if (argc == 5 ) {
@@ -198,116 +266,104 @@ int main(int argc, char **argv)
198
266
}
199
267
#endif
200
268
201
- /* Read the private key and the X.509 cert the PKCS#7 message
202
- * will point to.
203
- */
204
- if (!strncmp (private_key_name , "pkcs11:" , 7 )) {
205
- ENGINE * e ;
206
-
207
- ENGINE_load_builtin_engines ();
208
- drain_openssl_errors ();
209
- e = ENGINE_by_id ("pkcs11" );
210
- ERR (!e , "Load PKCS#11 ENGINE" );
211
- if (ENGINE_init (e ))
212
- drain_openssl_errors ();
213
- else
214
- ERR (1 , "ENGINE_init" );
215
- if (key_pass )
216
- ERR (!ENGINE_ctrl_cmd_string (e , "PIN" , key_pass , 0 ), "Set PKCS#11 PIN" );
217
- private_key = ENGINE_load_private_key (e , private_key_name , NULL ,
218
- NULL );
219
- ERR (!private_key , "%s" , private_key_name );
220
- } else {
221
- b = BIO_new_file (private_key_name , "rb" );
222
- ERR (!b , "%s" , private_key_name );
223
- private_key = PEM_read_bio_PrivateKey (b , NULL , pem_pw_cb , NULL );
224
- ERR (!private_key , "%s" , private_key_name );
225
- BIO_free (b );
226
- }
227
-
228
- b = BIO_new_file (x509_name , "rb" );
229
- ERR (!b , "%s" , x509_name );
230
- x509 = d2i_X509_bio (b , NULL ); /* Binary encoded X.509 */
231
- if (!x509 ) {
232
- ERR (BIO_reset (b ) != 1 , "%s" , x509_name );
233
- x509 = PEM_read_bio_X509 (b , NULL , NULL , NULL ); /* PEM encoded X.509 */
234
- if (x509 )
235
- drain_openssl_errors ();
236
- }
237
- BIO_free (b );
238
- ERR (!x509 , "%s" , x509_name );
239
-
240
- /* Open the destination file now so that we can shovel the module data
241
- * across as we read it.
242
- */
243
- if (!sign_only ) {
244
- bd = BIO_new_file (dest_name , "wb" );
245
- ERR (!bd , "%s" , dest_name );
246
- }
247
-
248
- /* Digest the module data. */
249
- OpenSSL_add_all_digests ();
250
- display_openssl_errors (__LINE__ );
251
- digest_algo = EVP_get_digestbyname (hash_algo );
252
- ERR (!digest_algo , "EVP_get_digestbyname" );
253
-
269
+ /* Open the module file */
254
270
bm = BIO_new_file (module_name , "rb" );
255
271
ERR (!bm , "%s" , module_name );
256
272
273
+ if (!raw_sig ) {
274
+ /* Read the private key and the X.509 cert the PKCS#7 message
275
+ * will point to.
276
+ */
277
+ private_key = read_private_key (private_key_name );
278
+ x509 = read_x509 (x509_name );
279
+
280
+ /* Digest the module data. */
281
+ OpenSSL_add_all_digests ();
282
+ display_openssl_errors (__LINE__ );
283
+ digest_algo = EVP_get_digestbyname (hash_algo );
284
+ ERR (!digest_algo , "EVP_get_digestbyname" );
285
+
257
286
#ifndef USE_PKCS7
258
- /* Load the signature message from the digest buffer. */
259
- cms = CMS_sign (NULL , NULL , NULL , NULL ,
260
- CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | CMS_DETACHED | CMS_STREAM );
261
- ERR (!cms , "CMS_sign" );
262
-
263
- ERR (!CMS_add1_signer (cms , x509 , private_key , digest_algo ,
264
- CMS_NOCERTS | CMS_BINARY | CMS_NOSMIMECAP |
265
- use_keyid | use_signed_attrs ),
266
- "CMS_add1_signer" );
267
- ERR (CMS_final (cms , bm , NULL , CMS_NOCERTS | CMS_BINARY ) < 0 ,
268
- "CMS_final" );
287
+ /* Load the signature message from the digest buffer. */
288
+ cms = CMS_sign (NULL , NULL , NULL , NULL ,
289
+ CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
290
+ CMS_DETACHED | CMS_STREAM );
291
+ ERR (!cms , "CMS_sign" );
292
+
293
+ ERR (!CMS_add1_signer (cms , x509 , private_key , digest_algo ,
294
+ CMS_NOCERTS | CMS_BINARY |
295
+ CMS_NOSMIMECAP | use_keyid |
296
+ use_signed_attrs ),
297
+ "CMS_add1_signer" );
298
+ ERR (CMS_final (cms , bm , NULL , CMS_NOCERTS | CMS_BINARY ) < 0 ,
299
+ "CMS_final" );
269
300
270
301
#else
271
- pkcs7 = PKCS7_sign (x509 , private_key , NULL , bm ,
272
- PKCS7_NOCERTS | PKCS7_BINARY |
273
- PKCS7_DETACHED | use_signed_attrs );
274
- ERR (!pkcs7 , "PKCS7_sign" );
302
+ pkcs7 = PKCS7_sign (x509 , private_key , NULL , bm ,
303
+ PKCS7_NOCERTS | PKCS7_BINARY |
304
+ PKCS7_DETACHED | use_signed_attrs );
305
+ ERR (!pkcs7 , "PKCS7_sign" );
275
306
#endif
276
307
277
- if (save_sig ) {
278
- char * sig_file_name ;
308
+ if (save_sig ) {
309
+ char * sig_file_name ;
310
+ BIO * b ;
279
311
280
- ERR (asprintf (& sig_file_name , "%s.p7s" , module_name ) < 0 ,
281
- "asprintf" );
282
- b = BIO_new_file (sig_file_name , "wb" );
283
- ERR (!b , "%s" , sig_file_name );
312
+ ERR (asprintf (& sig_file_name , "%s.p7s" , module_name ) < 0 ,
313
+ "asprintf" );
314
+ b = BIO_new_file (sig_file_name , "wb" );
315
+ ERR (!b , "%s" , sig_file_name );
284
316
#ifndef USE_PKCS7
285
- ERR (i2d_CMS_bio_stream (b , cms , NULL , 0 ) < 0 ,
286
- "%s" , sig_file_name );
317
+ ERR (i2d_CMS_bio_stream (b , cms , NULL , 0 ) < 0 ,
318
+ "%s" , sig_file_name );
287
319
#else
288
- ERR (i2d_PKCS7_bio (b , pkcs7 ) < 0 ,
289
- "%s" , sig_file_name );
320
+ ERR (i2d_PKCS7_bio (b , pkcs7 ) < 0 ,
321
+ "%s" , sig_file_name );
290
322
#endif
291
- BIO_free (b );
323
+ BIO_free (b );
324
+ }
325
+
326
+ if (sign_only ) {
327
+ BIO_free (bm );
328
+ return 0 ;
329
+ }
292
330
}
293
331
294
- if (sign_only )
295
- return 0 ;
332
+ /* Open the destination file now so that we can shovel the module data
333
+ * across as we read it.
334
+ */
335
+ bd = BIO_new_file (dest_name , "wb" );
336
+ ERR (!bd , "%s" , dest_name );
296
337
297
338
/* Append the marker and the PKCS#7 message to the destination file */
298
339
ERR (BIO_reset (bm ) < 0 , "%s" , module_name );
299
340
while ((n = BIO_read (bm , buf , sizeof (buf ))),
300
341
n > 0 ) {
301
342
ERR (BIO_write (bd , buf , n ) < 0 , "%s" , dest_name );
302
343
}
344
+ BIO_free (bm );
303
345
ERR (n < 0 , "%s" , module_name );
304
346
module_size = BIO_number_written (bd );
305
347
348
+ if (!raw_sig ) {
306
349
#ifndef USE_PKCS7
307
- ERR (i2d_CMS_bio_stream (bd , cms , NULL , 0 ) < 0 , "%s" , dest_name );
350
+ ERR (i2d_CMS_bio_stream (bd , cms , NULL , 0 ) < 0 , "%s" , dest_name );
308
351
#else
309
- ERR (i2d_PKCS7_bio (bd , pkcs7 ) < 0 , "%s" , dest_name );
352
+ ERR (i2d_PKCS7_bio (bd , pkcs7 ) < 0 , "%s" , dest_name );
310
353
#endif
354
+ } else {
355
+ BIO * b ;
356
+
357
+ /* Read the raw signature file and write the data to the
358
+ * destination file
359
+ */
360
+ b = BIO_new_file (raw_sig_name , "rb" );
361
+ ERR (!b , "%s" , raw_sig_name );
362
+ while ((n = BIO_read (b , buf , sizeof (buf ))), n > 0 )
363
+ ERR (BIO_write (bd , buf , n ) < 0 , "%s" , dest_name );
364
+ BIO_free (b );
365
+ }
366
+
311
367
sig_size = BIO_number_written (bd ) - module_size ;
312
368
sig_info .sig_len = htonl (sig_size );
313
369
ERR (BIO_write (bd , & sig_info , sizeof (sig_info )) < 0 , "%s" , dest_name );
0 commit comments