3 * Converting pkcs#1 and similar keys to sexp format. */
5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2005, 2009 Niels Möller, Magnus Holmgren
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston,
45 /* Use a range of values which also work as option id:s */
46 RSA_PRIVATE_KEY
= 0x200,
49 /* DSA public keys only supported as part of a
50 SubjectPublicKeyInfo, i.e., the GENERAL_PUBLIC_KEY case. */
55 write_file(struct nettle_buffer
*buffer
, FILE *f
)
57 size_t res
= fwrite(buffer
->contents
, 1, buffer
->size
, f
);
58 if (res
< buffer
->size
)
60 werror("Write failed: %s.\n", strerror(errno
));
67 /* Return 1 on success, 0 on error, -1 on eof */
69 read_line(struct nettle_buffer
*buffer
, FILE *f
)
73 while ((c
= getc(f
)) != EOF
)
75 if (!NETTLE_BUFFER_PUTC(buffer
, c
))
83 werror("Read failed: %s\n", strerror(errno
));
92 read_file(struct nettle_buffer
*buffer
, FILE *f
)
96 while ((c
= getc(f
)) != EOF
)
97 if (!NETTLE_BUFFER_PUTC(buffer
, c
))
102 werror("Read failed: %s\n", strerror(errno
));
110 pem_start_pattern
[11] = "-----BEGIN ";
113 pem_end_pattern
[9] = "-----END ";
116 pem_trailer_pattern
[5] = "-----";
120 0, 0, 0, 0, 0, 0, 0, 0,
121 0, 1, 1, 1, 1, 1, 0, 0, /* \t, \n, \v, \f, \r */
122 0, 0, 0, 0, 0, 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0,
127 #define PEM_IS_SPACE(c) ((c) < sizeof(pem_ws) && pem_ws[(c)])
129 /* Returns 1 on match, otherwise 0. */
131 match_pem_start(unsigned length
, const uint8_t *line
,
132 unsigned *marker_start
,
133 unsigned *marker_length
)
135 while (length
> 0 && PEM_IS_SPACE(line
[length
- 1]))
138 if (length
> (sizeof(pem_start_pattern
) + sizeof(pem_trailer_pattern
))
139 && memcmp(line
, pem_start_pattern
, sizeof(pem_start_pattern
)) == 0
140 && memcmp(line
+ length
- sizeof(pem_trailer_pattern
),
141 pem_trailer_pattern
, sizeof(pem_trailer_pattern
)) == 0)
144 *marker_length
= length
- (sizeof(pem_start_pattern
) + sizeof(pem_trailer_pattern
));
152 /* Returns 1 on match, -1 if the line is of the right form except for
153 the marker, otherwise 0. */
155 match_pem_end(unsigned length
, const uint8_t *line
,
156 unsigned marker_length
,
157 const uint8_t *marker
)
159 while (length
> 0 && PEM_IS_SPACE(line
[length
- 1]))
162 if (length
> (sizeof(pem_end_pattern
) + sizeof(pem_trailer_pattern
))
163 && memcmp(line
, pem_end_pattern
, sizeof(pem_end_pattern
)) == 0
164 && memcmp(line
+ length
- sizeof(pem_trailer_pattern
),
165 pem_trailer_pattern
, sizeof(pem_trailer_pattern
)) == 0)
167 /* Right form. Check marker */
168 if (length
== marker_length
+ (sizeof(pem_end_pattern
) + sizeof(pem_trailer_pattern
))
169 && memcmp(line
+ sizeof(pem_end_pattern
), marker
, marker_length
) == 0)
180 /* The FOO part in "-----BEGIN FOO-----" */
181 unsigned marker_start
;
182 unsigned marker_length
;
184 unsigned data_length
;
188 read_pem(struct nettle_buffer
*buffer
, FILE *f
,
189 struct pem_info
*info
)
191 /* Find start line */
196 nettle_buffer_reset(buffer
);
198 res
= read_line(buffer
, f
);
202 if (match_pem_start(buffer
->size
, buffer
->contents
,
203 &info
->marker_start
, &info
->marker_length
))
207 /* NUL-terminate the marker. Don't care to check for embedded NULs. */
208 buffer
->contents
[info
->marker_start
+ info
->marker_length
] = 0;
210 info
->data_start
= buffer
->size
;
214 unsigned line_start
= buffer
->size
;
216 if (read_line(buffer
, f
) != 1)
219 switch (match_pem_end(buffer
->size
- line_start
,
220 buffer
->contents
+ line_start
,
222 buffer
->contents
+ info
->marker_start
))
227 werror("PEM END line doesn't match BEGIN.\n");
230 /* Return base 64 data; let caller do the decoding */
231 info
->data_length
= line_start
- info
->data_start
;
238 decode_base64(struct nettle_buffer
*buffer
,
239 unsigned start
, unsigned *length
)
241 struct base64_decode_ctx ctx
;
243 base64_decode_init(&ctx
);
245 /* Decode in place */
246 if (base64_decode_update(&ctx
,
247 length
, buffer
->contents
+ start
,
248 *length
, buffer
->contents
+ start
)
249 && base64_decode_final(&ctx
))
254 werror("Invalid base64 date.\n");
260 convert_rsa_public_key(struct nettle_buffer
*buffer
, unsigned length
, const uint8_t *data
)
262 struct rsa_public_key pub
;
265 rsa_public_key_init(&pub
);
267 if (rsa_keypair_from_der(&pub
, NULL
, 0,
270 /* Reuses the buffer */
271 nettle_buffer_reset(buffer
);
272 res
= rsa_keypair_to_sexp(buffer
, NULL
, &pub
, NULL
);
276 werror("Invalid PKCS#1 public key.\n");
279 rsa_public_key_clear(&pub
);
284 convert_rsa_private_key(struct nettle_buffer
*buffer
, unsigned length
, const uint8_t *data
)
286 struct rsa_public_key pub
;
287 struct rsa_private_key priv
;
290 rsa_public_key_init(&pub
);
291 rsa_private_key_init(&priv
);
293 if (rsa_keypair_from_der(&pub
, &priv
, 0,
296 /* Reuses the buffer */
297 nettle_buffer_reset(buffer
);
298 res
= rsa_keypair_to_sexp(buffer
, NULL
, &pub
, &priv
);
302 werror("Invalid PKCS#1 private key.\n");
305 rsa_public_key_clear(&pub
);
306 rsa_private_key_clear(&priv
);
312 convert_dsa_private_key(struct nettle_buffer
*buffer
, unsigned length
, const uint8_t *data
)
314 struct dsa_public_key pub
;
315 struct dsa_private_key priv
;
318 dsa_public_key_init(&pub
);
319 dsa_private_key_init(&priv
);
321 if (dsa_openssl_private_key_from_der(&pub
, &priv
, 0,
324 /* Reuses the buffer */
325 nettle_buffer_reset(buffer
);
326 res
= dsa_keypair_to_sexp(buffer
, NULL
, &pub
, &priv
);
330 werror("Invalid OpenSSL private key.\n");
333 dsa_public_key_clear(&pub
);
334 dsa_private_key_clear(&priv
);
339 /* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
341 convert_public_key(struct nettle_buffer
*buffer
, unsigned length
, const uint8_t *data
)
343 /* SubjectPublicKeyInfo ::= SEQUENCE {
344 algorithm AlgorithmIdentifier,
345 subjectPublicKey BIT STRING
348 AlgorithmIdentifier ::= SEQUENCE {
349 algorithm OBJECT IDENTIFIER,
353 struct asn1_der_iterator i
;
354 struct asn1_der_iterator j
;
357 if (asn1_der_iterator_first(&i
, length
, data
) == ASN1_ITERATOR_CONSTRUCTED
358 && i
.type
== ASN1_SEQUENCE
359 && asn1_der_decode_constructed_last(&i
) == ASN1_ITERATOR_CONSTRUCTED
360 && i
.type
== ASN1_SEQUENCE
362 /* Use the j iterator to parse the algorithm identifier */
363 && asn1_der_decode_constructed(&i
, &j
) == ASN1_ITERATOR_PRIMITIVE
364 && j
.type
== ASN1_IDENTIFIER
365 && asn1_der_iterator_next(&i
) == ASN1_ITERATOR_PRIMITIVE
366 && i
.type
== ASN1_BITSTRING
368 /* Use i to parse the object wrapped in the bit string.*/
369 && asn1_der_decode_bitstring_last(&i
))
372 iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
377 -- When rsaEncryption is used in an AlgorithmIdentifier the
378 -- parameters MUST be present and MUST be NULL.
380 rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
382 static const uint8_t id_rsaEncryption
[9] =
383 { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
386 -- When dsa is used in an AlgorithmIdentifier the
387 -- parameters MUST be present and MUST NOT be NULL.
389 dsa OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
391 static const uint8_t id_dsa
[7] =
392 { 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 };
398 werror("SubjectPublicKeyInfo: Unsupported algorithm.\n");
403 if (memcmp(j
.data
, id_dsa
, 7) == 0)
405 if (asn1_der_iterator_next(&j
) == ASN1_ITERATOR_CONSTRUCTED
406 && asn1_der_decode_constructed_last(&j
) == ASN1_ITERATOR_PRIMITIVE
)
408 struct dsa_public_key pub
;
410 dsa_public_key_init(&pub
);
412 if (dsa_params_from_der_iterator(&pub
, 0, &i
)
413 && dsa_public_key_from_der_iterator(&pub
, 0, &j
))
415 nettle_buffer_reset(buffer
);
416 res
= dsa_keypair_to_sexp(buffer
, NULL
, &pub
, NULL
) > 0;
418 dsa_public_key_clear(&pub
);
421 werror("SubjectPublicKeyInfo: Invalid DSA key.\n");
426 if (memcmp(j
.data
, id_rsaEncryption
, 9) == 0)
428 if (asn1_der_iterator_next(&j
) == ASN1_ITERATOR_PRIMITIVE
429 && j
.type
== ASN1_NULL
431 && asn1_der_iterator_next(&j
) == ASN1_ITERATOR_END
)
433 struct rsa_public_key pub
;
435 rsa_public_key_init(&pub
);
437 if (rsa_public_key_from_der_iterator(&pub
, 0, &i
))
439 nettle_buffer_reset(buffer
);
440 res
= rsa_keypair_to_sexp(buffer
, NULL
, &pub
, NULL
) > 0;
442 rsa_public_key_clear(&pub
);
445 werror("SubjectPublicKeyInfo: Invalid RSA key.\n");
452 werror("SubjectPublicKeyInfo: Invalid object.\n");
457 /* NOTE: Destroys contents of buffer */
458 /* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
460 convert_type(struct nettle_buffer
*buffer
,
461 enum object_type type
,
462 unsigned length
, const uint8_t *data
)
471 case GENERAL_PUBLIC_KEY
:
472 res
= convert_public_key(buffer
, length
, data
);
476 res
= convert_rsa_public_key(buffer
, length
, data
);
479 case RSA_PRIVATE_KEY
:
480 res
= convert_rsa_private_key(buffer
, length
, data
);
483 case DSA_PRIVATE_KEY
:
484 res
= convert_dsa_private_key(buffer
, length
, data
);
489 res
= write_file(buffer
, stdout
);
495 convert_file(struct nettle_buffer
*buffer
,
497 enum object_type type
,
502 read_file(buffer
, f
);
503 if (base64
&& !decode_base64(buffer
, 0, &buffer
->size
))
506 if (convert_type(buffer
, type
,
507 buffer
->size
, buffer
->contents
) != 1)
517 struct pem_info info
;
518 const uint8_t *marker
;
520 nettle_buffer_reset(buffer
);
521 switch (read_pem(buffer
, f
, &info
))
532 if (!decode_base64(buffer
, info
.data_start
, &info
.data_length
))
535 marker
= buffer
->contents
+ info
.marker_start
;
538 switch (info
.marker_length
)
541 if (memcmp(marker
, "PUBLIC KEY", 10) == 0)
543 type
= GENERAL_PUBLIC_KEY
;
547 if (memcmp(marker
, "RSA PUBLIC KEY", 14) == 0)
549 type
= RSA_PUBLIC_KEY
;
554 if (memcmp(marker
, "RSA PRIVATE KEY", 15) == 0)
556 type
= RSA_PRIVATE_KEY
;
559 if (memcmp(marker
, "DSA PRIVATE KEY", 15) == 0)
561 type
= DSA_PRIVATE_KEY
;
567 werror("Ignoring unsupported object type `%s'.\n", marker
);
569 else if (convert_type(buffer
, type
,
571 buffer
->contents
+ info
.data_start
) != 1)
578 main(int argc
, char **argv
)
580 struct nettle_buffer buffer
;
581 enum object_type type
= 0;
587 OPT_PRIVATE_RSA
= RSA_PRIVATE_KEY
,
588 OPT_PUBLIC_RSA
= RSA_PUBLIC_KEY
,
589 OPT_PRIVATE_DSA
= DSA_PRIVATE_KEY
,
590 OPT_PUBLIC_KEY
= GENERAL_PUBLIC_KEY
,
593 static const struct option options
[] =
595 /* Name, args, flag, val */
596 { "help", no_argument
, NULL
, OPT_HELP
},
597 { "version", no_argument
, NULL
, 'V' },
598 { "private-rsa-key", no_argument
, NULL
, OPT_PRIVATE_RSA
},
599 { "public-rsa-key", no_argument
, NULL
, OPT_PUBLIC_RSA
},
600 { "private-dsa-key", no_argument
, NULL
, OPT_PRIVATE_DSA
},
601 { "public-key-info", no_argument
, NULL
, OPT_PUBLIC_KEY
},
602 { "base-64", no_argument
, NULL
, 'b' },
606 while ( (c
= getopt_long(argc
, argv
, "Vb", options
, NULL
)) != -1)
617 case OPT_PRIVATE_RSA
:
619 case OPT_PRIVATE_DSA
:
621 /* Same values as the type codes. */
626 printf("FIXME: Usage information.\n");
632 printf("pkcs1-conv (" PACKAGE_STRING
")\n");
637 nettle_buffer_init_realloc(&buffer
, NULL
, nettle_xrealloc
);
641 if (!convert_file(&buffer
, stdin
, type
, base64
))
647 const char *mode
= (type
|| base64
) ? "r" : "rb";
649 for (i
= optind
; i
< argc
; i
++)
651 FILE *f
= fopen(argv
[i
], mode
);
653 die("Failed to open `%s': %s.\n", argv
[i
], strerror(errno
));
655 if (!convert_file(&buffer
, f
, type
, base64
))
661 nettle_buffer_clear (&buffer
);