9e346858b18273ba37cb38a8a658cd071ad169b0
[platform/upstream/nettle.git] / tools / pkcs1-conv.c
1 /* pkcs1-conv.c
2
3    Converting pkcs#1 and related keys to sexp format.
4
5    Copyright (C) 2005, 2009 Niels Möller, Magnus Holmgren
6    Copyright (C) 2014 Niels Möller
7
8    This file is part of GNU Nettle.
9
10    GNU Nettle is free software: you can redistribute it and/or
11    modify it under the terms of either:
12
13      * the GNU Lesser General Public License as published by the Free
14        Software Foundation; either version 3 of the License, or (at your
15        option) any later version.
16
17    or
18
19      * the GNU General Public License as published by the Free
20        Software Foundation; either version 2 of the License, or (at your
21        option) any later version.
22
23    or both in parallel, as here.
24
25    GNU Nettle is distributed in the hope that it will be useful,
26    but WITHOUT ANY WARRANTY; without even the implied warranty of
27    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
28    General Public License for more details.
29
30    You should have received copies of the GNU General Public License and
31    the GNU Lesser General Public License along with this program.  If
32    not, see http://www.gnu.org/licenses/.
33 */
34
35 #if HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38
39 #include <errno.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include "asn1.h"
45 #include "base64.h"
46 #include "buffer.h"
47 #include "rsa.h"
48 #include "dsa.h"
49
50 #include "getopt.h"
51 #include "misc.h"
52
53 enum object_type
54   {
55     /* Use a range of values which also work as option id:s */
56     RSA_PRIVATE_KEY = 0x200,
57     RSA_PUBLIC_KEY,
58     DSA_PRIVATE_KEY,
59     /* DSA public keys only supported as part of a
60        SubjectPublicKeyInfo, i.e., the GENERAL_PUBLIC_KEY case. */
61     GENERAL_PUBLIC_KEY,
62   };
63
64 static int
65 write_file(struct nettle_buffer *buffer, FILE *f)
66 {
67   size_t res = fwrite(buffer->contents, 1, buffer->size, f);
68   if (res < buffer->size)
69     {
70       werror("Write failed: %s.\n", strerror(errno));
71       return 0;
72     }
73   else
74     return 1;
75 }
76
77 /* Return 1 on success, 0 on error, -1 on eof */
78 static int
79 read_line(struct nettle_buffer *buffer, FILE *f)
80 {
81   int c;
82   
83   while ((c = getc(f)) != EOF)
84     {
85       if (!NETTLE_BUFFER_PUTC(buffer, c))
86         return 0;
87
88       if (c == '\n')
89         return 1;
90     }
91   if (ferror(f))
92     {
93       werror("Read failed: %s\n", strerror(errno));
94       return 0;
95     }
96   
97   else 
98     return -1;
99 }
100
101 static int
102 read_file(struct nettle_buffer *buffer, FILE *f)
103 {
104   int c;
105   
106   while ((c = getc(f)) != EOF)
107     if (!NETTLE_BUFFER_PUTC(buffer, c))
108       return 0;
109
110   if (ferror(f))
111     {
112       werror("Read failed: %s\n", strerror(errno));
113       return 0;
114     }
115   else
116     return 1;
117 }
118
119 static const uint8_t
120 pem_start_pattern[11] = "-----BEGIN ";
121
122 static const uint8_t
123 pem_end_pattern[9] = "-----END ";
124
125 static const uint8_t
126 pem_trailer_pattern[5] = "-----";
127
128 static const char
129 pem_ws[33] = {
130   0, 0, 0, 0, 0, 0, 0, 0,
131   0, 1, 1, 1, 1, 1, 0, 0, /* \t, \n, \v, \f, \r */
132   0, 0, 0, 0, 0, 0, 0, 0,
133   0, 0, 0, 0, 0, 0, 0, 0,
134   1 /* SPC */
135 };
136
137 #define PEM_IS_SPACE(c) ((c) < sizeof(pem_ws) && pem_ws[(c)]) 
138
139 /* Returns 1 on match, otherwise 0. */ 
140 static int
141 match_pem_start(size_t length, const uint8_t *line,
142                 size_t *marker_start,
143                 size_t *marker_length)
144 {
145   while (length > 0 && PEM_IS_SPACE(line[length - 1]))
146     length--;
147
148   if (length > (sizeof(pem_start_pattern) + sizeof(pem_trailer_pattern))
149       && memcmp(line, pem_start_pattern, sizeof(pem_start_pattern)) == 0
150       && memcmp(line + length - sizeof(pem_trailer_pattern),
151                 pem_trailer_pattern, sizeof(pem_trailer_pattern)) == 0)
152     {
153       *marker_start = 11;
154       *marker_length = length - (sizeof(pem_start_pattern) + sizeof(pem_trailer_pattern));
155
156       return 1;
157     }
158   else
159     return 0;
160 }
161
162 /* Returns 1 on match, -1 if the line is of the right form except for
163    the marker, otherwise 0. */ 
164 static int
165 match_pem_end(size_t length, const uint8_t *line,
166               size_t marker_length,
167               const uint8_t *marker)
168 {
169   while (length > 0 && PEM_IS_SPACE(line[length - 1]))
170     length--;
171
172   if (length > (sizeof(pem_end_pattern) + sizeof(pem_trailer_pattern))
173       && memcmp(line, pem_end_pattern, sizeof(pem_end_pattern)) == 0
174       && memcmp(line + length - sizeof(pem_trailer_pattern),
175                 pem_trailer_pattern, sizeof(pem_trailer_pattern)) == 0)
176     {
177       /* Right form. Check marker */
178       if (length == marker_length + (sizeof(pem_end_pattern) + sizeof(pem_trailer_pattern))
179           && memcmp(line + sizeof(pem_end_pattern), marker, marker_length) == 0)
180         return 1;
181       else
182         return -1;
183     }
184   else
185     return 0;  
186 }
187
188 struct pem_info
189 {
190   /* The FOO part in "-----BEGIN FOO-----" */
191   size_t marker_start;
192   size_t marker_length;
193   size_t data_start;
194   size_t data_length;
195 };
196
197 static int
198 read_pem(struct nettle_buffer *buffer, FILE *f,
199          struct pem_info *info)
200 {  
201   /* Find start line */
202   for (;;)
203     {
204       int res;
205
206       nettle_buffer_reset(buffer);
207
208       res = read_line(buffer, f);
209       if (res != 1)
210         return res;
211
212       if (match_pem_start(buffer->size, buffer->contents,
213                           &info->marker_start, &info->marker_length))
214         break;
215     }
216
217   /* NUL-terminate the marker. Don't care to check for embedded NULs. */
218   buffer->contents[info->marker_start + info->marker_length] = 0;
219
220   info->data_start = buffer->size;
221
222   for (;;)
223     {
224       size_t line_start = buffer->size;
225
226       if (read_line(buffer, f) != 1)
227         return 0;
228
229       switch (match_pem_end(buffer->size - line_start,
230                             buffer->contents + line_start,
231                             info->marker_length,
232                             buffer->contents + info->marker_start))
233         {
234         case 0:
235           break;
236         case -1:
237           werror("PEM END line doesn't match BEGIN.\n");
238           return 0;
239         case 1:
240           /* Return base 64 data; let caller do the decoding */ 
241           info->data_length = line_start - info->data_start;
242           return 1;
243         }
244     }
245 }
246
247 static int
248 decode_base64(struct nettle_buffer *buffer,
249               size_t start, size_t *length)
250 {
251   struct base64_decode_ctx ctx;
252   
253   base64_decode_init(&ctx);
254
255   /* Decode in place */
256   if (base64_decode_update(&ctx,
257                            length, buffer->contents + start,
258                            *length, buffer->contents + start)
259       && base64_decode_final(&ctx))
260     return 1;
261   
262   else
263     {
264       werror("Invalid base64 date.\n");
265       return 0;
266     }
267 }
268
269 static int
270 convert_rsa_public_key(struct nettle_buffer *buffer, size_t length, const uint8_t *data)
271 {
272   struct rsa_public_key pub;
273   int res;
274   
275   rsa_public_key_init(&pub);
276
277   if (rsa_keypair_from_der(&pub, NULL, 0,
278                            length, data))
279     {
280       /* Reuses the buffer */
281       nettle_buffer_reset(buffer);
282       res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL);
283     }
284   else
285     {
286       werror("Invalid PKCS#1 public key.\n");
287       res = 0;
288     }
289   rsa_public_key_clear(&pub);
290   return res;
291 }
292
293 static int
294 convert_rsa_private_key(struct nettle_buffer *buffer, size_t length, const uint8_t *data)
295 {
296   struct rsa_public_key pub;
297   struct rsa_private_key priv;
298   int res;
299   
300   rsa_public_key_init(&pub);
301   rsa_private_key_init(&priv);
302
303   if (rsa_keypair_from_der(&pub, &priv, 0,
304                            length, data))
305     {
306       /* Reuses the buffer */
307       nettle_buffer_reset(buffer);
308       res = rsa_keypair_to_sexp(buffer, NULL, &pub, &priv);
309     }
310   else
311     {
312       werror("Invalid PKCS#1 private key.\n");
313       res = 0;
314     }
315   rsa_public_key_clear(&pub);
316   rsa_private_key_clear(&priv);
317
318   return res;
319 }
320
321 static int
322 convert_dsa_private_key(struct nettle_buffer *buffer, size_t length, const uint8_t *data)
323 {
324   struct dsa_params params;
325   mpz_t pub;
326   mpz_t priv;
327   int res;
328
329   dsa_params_init (&params);
330   mpz_init (pub);
331   mpz_init (priv);
332
333   if (dsa_openssl_private_key_from_der(&params, pub, priv, 0,
334                                        length, data))
335     {
336       /* Reuses the buffer */
337       nettle_buffer_reset(buffer);
338       res = dsa_keypair_to_sexp(buffer, NULL, &params, pub, priv);
339     }
340   else
341     {
342       werror("Invalid OpenSSL private key.\n");
343       res = 0;
344     }
345   dsa_params_clear (&params);
346   mpz_clear (pub);
347   mpz_clear (priv);
348
349   return res;
350 }
351
352 /* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
353 static int
354 convert_public_key(struct nettle_buffer *buffer, size_t length, const uint8_t *data)
355 {
356   /* SubjectPublicKeyInfo ::= SEQUENCE {
357          algorithm              AlgorithmIdentifier,
358          subjectPublicKey       BIT STRING
359      }
360
361      AlgorithmIdentifier ::= SEQUENCE {
362          algorithm      OBJECT IDENTIFIER,
363          parameters     OPTIONAL
364      }
365   */
366   struct asn1_der_iterator i;
367   struct asn1_der_iterator j;
368   int res = 0;
369
370   if (asn1_der_iterator_first(&i, length, data) == ASN1_ITERATOR_CONSTRUCTED
371       && i.type == ASN1_SEQUENCE
372       && asn1_der_decode_constructed_last(&i) == ASN1_ITERATOR_CONSTRUCTED
373       && i.type == ASN1_SEQUENCE
374
375       /* Use the j iterator to parse the algorithm identifier */
376       && asn1_der_decode_constructed(&i, &j) == ASN1_ITERATOR_PRIMITIVE
377       && j.type == ASN1_IDENTIFIER
378       && asn1_der_iterator_next(&i) == ASN1_ITERATOR_PRIMITIVE
379       && i.type == ASN1_BITSTRING
380
381       /* Use i to parse the object wrapped in the bit string.*/
382       && asn1_der_decode_bitstring_last(&i))
383     {
384       /* pkcs-1 {
385              iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
386              modules(0) pkcs-1(1)
387          }
388
389          --
390          -- When rsaEncryption is used in an AlgorithmIdentifier the
391          -- parameters MUST be present and MUST be NULL.
392          --
393          rsaEncryption    OBJECT IDENTIFIER ::= { pkcs-1 1 }
394       */
395       static const uint8_t id_rsaEncryption[9] =
396         { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
397       /*
398          --
399          -- When dsa is used in an AlgorithmIdentifier the
400          -- parameters MUST be present and MUST NOT be NULL.
401          --
402          dsa    OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
403       */
404       static const uint8_t id_dsa[7] =
405         { 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 };
406
407       switch (j.length)
408         {
409         unknown:
410         default:
411           werror("SubjectPublicKeyInfo: Unsupported algorithm.\n");
412           res = -1;
413           break;
414           
415         case 7:
416           if (memcmp(j.data, id_dsa, 7) == 0)
417             {
418               if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_CONSTRUCTED
419                   && asn1_der_decode_constructed_last(&j) == ASN1_ITERATOR_PRIMITIVE)
420                 {
421                   struct dsa_params params;
422                   mpz_t pub;
423
424                   dsa_params_init (&params);
425                   mpz_init (pub);
426
427                   if (dsa_params_from_der_iterator(&params, 0, 0, &i)
428                       && dsa_public_key_from_der_iterator(&params, pub, &j))
429                     {
430                       nettle_buffer_reset(buffer);
431                       res = dsa_keypair_to_sexp(buffer, NULL,
432                                                 &params, pub, NULL) > 0;
433                     }
434                   dsa_params_clear(&params);
435                   mpz_clear(pub);
436                 }
437               if (!res)
438                 werror("SubjectPublicKeyInfo: Invalid DSA key.\n");
439               break;
440             }
441           else goto unknown;
442         case 9:
443           if (memcmp(j.data, id_rsaEncryption, 9) == 0)
444             {
445               if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_PRIMITIVE
446                   && j.type == ASN1_NULL
447                   && j.length == 0
448                   && asn1_der_iterator_next(&j) == ASN1_ITERATOR_END)
449                 {
450                   struct rsa_public_key pub;
451
452                   rsa_public_key_init(&pub);
453
454                   if (rsa_public_key_from_der_iterator(&pub, 0, &i))
455                     {
456                       nettle_buffer_reset(buffer);
457                       res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0;
458                     }
459                   rsa_public_key_clear(&pub);
460                 }
461               if (!res)
462                 werror("SubjectPublicKeyInfo: Invalid RSA key.\n");
463               break;
464             }
465           else goto unknown;
466         }
467     }
468   else
469     werror("SubjectPublicKeyInfo: Invalid object.\n");
470
471   return res;
472 }
473
474 /* NOTE: Destroys contents of buffer */
475 /* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
476 static int
477 convert_type(struct nettle_buffer *buffer,
478              enum object_type type,
479              size_t length, const uint8_t *data)
480 {
481   int res;
482   
483   switch(type)
484     {
485     default:
486       abort();
487
488     case GENERAL_PUBLIC_KEY:
489       res = convert_public_key(buffer, length, data);
490       break;
491
492     case RSA_PUBLIC_KEY:
493       res = convert_rsa_public_key(buffer, length, data);
494       break;
495
496     case RSA_PRIVATE_KEY:
497       res = convert_rsa_private_key(buffer, length, data);
498       break;
499
500     case DSA_PRIVATE_KEY:
501       res = convert_dsa_private_key(buffer, length, data);
502       break;
503     }
504
505   if (res > 0)
506     res = write_file(buffer, stdout);
507
508   return res;
509 }
510
511 static int
512 convert_file(struct nettle_buffer *buffer,
513              FILE *f,
514              enum object_type type,
515              int base64)
516 {
517   if (type)
518     {
519       read_file(buffer, f);
520       if (base64 && !decode_base64(buffer, 0, &buffer->size))
521         return 0;
522       
523       if (convert_type(buffer, type,
524                        buffer->size, buffer->contents) != 1)
525         return 0;
526
527       return 1;
528     }
529   else
530     {
531       /* PEM processing */
532       for (;;)
533         {
534           struct pem_info info;
535           const uint8_t *marker;
536           
537           nettle_buffer_reset(buffer);
538           switch (read_pem(buffer, f, &info))
539             {
540             default:
541               return 0;
542             case 1:
543               break;
544             case -1:
545               /* EOF */
546               return 1;
547             }
548
549           if (!decode_base64(buffer, info.data_start, &info.data_length))
550             return 0;
551
552           marker = buffer->contents + info.marker_start;
553
554           type = 0;
555           switch (info.marker_length)
556             {
557             case 10:
558               if (memcmp(marker, "PUBLIC KEY", 10) == 0)
559                 {
560                   type = GENERAL_PUBLIC_KEY;
561                   break;
562                 }
563             case 14:
564               if (memcmp(marker, "RSA PUBLIC KEY", 14) == 0)
565                 {
566                   type = RSA_PUBLIC_KEY;
567                   break;
568                 }
569
570             case 15:
571               if (memcmp(marker, "RSA PRIVATE KEY", 15) == 0)
572                 {
573                   type = RSA_PRIVATE_KEY;
574                   break;
575                 }
576               if (memcmp(marker, "DSA PRIVATE KEY", 15) == 0)
577                 {
578                   type = DSA_PRIVATE_KEY;
579                   break;
580                 }
581             }
582           
583           if (!type)
584             werror("Ignoring unsupported object type `%s'.\n", marker);
585
586           else if (convert_type(buffer, type,
587                                 info.data_length,
588                                 buffer->contents + info.data_start) != 1)
589             return 0;
590         }
591     }
592 }
593
594 int
595 main(int argc, char **argv)
596 {
597   struct nettle_buffer buffer;
598   enum object_type type = 0;
599   int base64 = 0;
600   int c;
601
602   enum {
603     OPT_HELP = 0x300,
604     OPT_PRIVATE_RSA = RSA_PRIVATE_KEY,
605     OPT_PUBLIC_RSA = RSA_PUBLIC_KEY,
606     OPT_PRIVATE_DSA = DSA_PRIVATE_KEY,
607     OPT_PUBLIC_KEY = GENERAL_PUBLIC_KEY,
608   };
609   
610   static const struct option options[] =
611     {
612       /* Name, args, flag, val */
613       { "help", no_argument, NULL, OPT_HELP },
614       { "version", no_argument, NULL, 'V' },
615       { "private-rsa-key", no_argument, NULL, OPT_PRIVATE_RSA },
616       { "public-rsa-key", no_argument, NULL, OPT_PUBLIC_RSA },
617       { "private-dsa-key", no_argument, NULL, OPT_PRIVATE_DSA },
618       { "public-key-info", no_argument, NULL, OPT_PUBLIC_KEY },
619       { "base-64", no_argument, NULL, 'b' },
620       { NULL, 0, NULL, 0 }
621     };
622
623   while ( (c = getopt_long(argc, argv, "Vb", options, NULL)) != -1)
624     {
625       switch (c)
626         {
627         default:
628           abort();
629
630         case 'b':
631           base64 = 1;
632           break;
633
634         case OPT_PRIVATE_RSA:
635         case OPT_PUBLIC_RSA:
636         case OPT_PRIVATE_DSA:
637         case OPT_PUBLIC_KEY:
638           /* Same values as the type codes. */
639           type = c;
640           break;
641
642         case OPT_HELP:
643           printf("FIXME: Usage information.\n");
644           return EXIT_SUCCESS;
645         case '?':
646           return EXIT_FAILURE;
647
648         case 'V':
649           printf("pkcs1-conv (" PACKAGE_STRING ")\n");
650           return EXIT_SUCCESS;
651         }
652     }
653
654   nettle_buffer_init_realloc(&buffer, NULL, nettle_xrealloc);  
655
656   if (optind == argc)
657     {
658       if (!convert_file(&buffer, stdin, type, base64))
659         return EXIT_FAILURE;
660     }
661   else
662     {
663       int i;
664       const char *mode = (type || base64) ? "r" : "rb";
665       
666       for (i = optind; i < argc; i++)
667         {
668           FILE *f = fopen(argv[i], mode);
669           if (!f)
670             die("Failed to open `%s': %s.\n", argv[i], strerror(errno));
671
672           if (!convert_file(&buffer, f, type, base64))
673             return EXIT_FAILURE;
674
675           fclose(f);
676         }
677     }
678   nettle_buffer_clear (&buffer);
679
680   return EXIT_SUCCESS;
681 }