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