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., 59 Temple Place - Suite 330, Boston,
45 RSA_PRIVATE_KEY = 0x200,
48 /* DSA public keys only supported as part of a
49 SubjectPublicKeyInfo, i.e., the GENERAL_PUBLIC_KEY case. */
54 write_file(struct nettle_buffer *buffer, FILE *f)
56 size_t res = fwrite(buffer->contents, 1, buffer->size, f);
57 if (res < buffer->size)
59 werror("Write failed: %s.\n", strerror(errno));
66 /* Return 1 on success, 0 on error, -1 on eof */
68 read_line(struct nettle_buffer *buffer, FILE *f)
72 while ((c = getc(f)) != EOF)
74 if (!NETTLE_BUFFER_PUTC(buffer, c))
82 werror("Read failed: %s\n", strerror(errno));
91 read_file(struct nettle_buffer *buffer, FILE *f)
95 while ((c = getc(f)) != EOF)
96 if (!NETTLE_BUFFER_PUTC(buffer, c))
101 werror("Read failed: %s\n", strerror(errno));
109 pem_start_pattern[11] = "-----BEGIN ";
112 pem_end_pattern[9] = "-----END ";
115 pem_trailer_pattern[5] = "-----";
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,
126 #define PEM_IS_SPACE(c) ((c) < sizeof(pem_ws) && pem_ws[(c)])
128 /* Returns 1 on match, otherwise 0. */
130 match_pem_start(unsigned length, const uint8_t *line,
131 unsigned *marker_start,
132 unsigned *marker_length)
134 while (length > 0 && PEM_IS_SPACE(line[length - 1]))
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)
143 *marker_length = length - (sizeof(pem_start_pattern) + sizeof(pem_trailer_pattern));
151 /* Returns 1 on match, -1 if the line is of the right form except for
152 the marker, otherwise 0. */
154 match_pem_end(unsigned length, const uint8_t *line,
155 unsigned marker_length,
156 const uint8_t *marker)
158 while (length > 0 && PEM_IS_SPACE(line[length - 1]))
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)
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)
179 /* The FOO part in "-----BEGIN FOO-----" */
180 unsigned marker_start;
181 unsigned marker_length;
183 unsigned data_length;
187 read_pem(struct nettle_buffer *buffer, FILE *f,
188 struct pem_info *info)
190 /* Find start line */
195 nettle_buffer_reset(buffer);
197 res = read_line(buffer, f);
201 if (match_pem_start(buffer->size, buffer->contents,
202 &info->marker_start, &info->marker_length))
206 /* NUL-terminate the marker. Don't care to check for embedded NULs. */
207 buffer->contents[info->marker_start + info->marker_length] = 0;
209 info->data_start = buffer->size;
213 unsigned line_start = buffer->size;
215 if (read_line(buffer, f) != 1)
218 switch (match_pem_end(buffer->size - line_start,
219 buffer->contents + line_start,
221 buffer->contents + info->marker_start))
226 werror("PEM END line doesn't match BEGIN.\n");
229 /* Return base 64 data; let caller do the decoding */
230 info->data_length = line_start - info->data_start;
237 decode_base64(struct nettle_buffer *buffer,
238 unsigned start, unsigned *length)
240 struct base64_decode_ctx ctx;
242 base64_decode_init(&ctx);
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))
253 werror("Invalid base64 date.\n");
259 convert_rsa_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
261 struct rsa_public_key pub;
264 rsa_public_key_init(&pub);
266 if (rsa_keypair_from_der(&pub, NULL, 0,
269 /* Reuses the buffer */
270 nettle_buffer_reset(buffer);
271 res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL);
275 werror("Invalid PKCS#1 public key.\n");
278 rsa_public_key_clear(&pub);
283 convert_rsa_private_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
285 struct rsa_public_key pub;
286 struct rsa_private_key priv;
289 rsa_public_key_init(&pub);
290 rsa_private_key_init(&priv);
292 if (rsa_keypair_from_der(&pub, &priv, 0,
295 /* Reuses the buffer */
296 nettle_buffer_reset(buffer);
297 res = rsa_keypair_to_sexp(buffer, NULL, &pub, &priv);
301 werror("Invalid PKCS#1 private key.\n");
304 rsa_public_key_clear(&pub);
305 rsa_private_key_clear(&priv);
311 convert_dsa_private_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
313 struct dsa_public_key pub;
314 struct dsa_private_key priv;
317 dsa_public_key_init(&pub);
318 dsa_private_key_init(&priv);
320 if (dsa_openssl_private_key_from_der(&pub, &priv, 0,
323 /* Reuses the buffer */
324 nettle_buffer_reset(buffer);
325 res = dsa_keypair_to_sexp(buffer, NULL, &pub, &priv);
329 werror("Invalid OpenSSL private key.\n");
332 dsa_public_key_clear(&pub);
333 dsa_private_key_clear(&priv);
338 /* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
340 convert_public_key(struct nettle_buffer *buffer, unsigned length, const uint8_t *data)
342 /* SubjectPublicKeyInfo ::= SEQUENCE {
343 algorithm AlgorithmIdentifier,
344 subjectPublicKey BIT STRING
347 AlgorithmIdentifier ::= SEQUENCE {
348 algorithm OBJECT IDENTIFIER,
352 struct asn1_der_iterator i;
353 struct asn1_der_iterator j;
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
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
367 /* Use i to parse the object wrapped in the bit string.*/
368 && asn1_der_decode_bitstring_last(&i))
371 iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
376 -- When rsaEncryption is used in an AlgorithmIdentifier the
377 -- parameters MUST be present and MUST be NULL.
379 rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
381 static const uint8_t id_rsaEncryption[9] =
382 { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
385 -- When dsa is used in an AlgorithmIdentifier the
386 -- parameters MUST be present and MUST NOT be NULL.
388 dsa OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
390 static const uint8_t id_dsa[7] =
391 { 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 };
397 werror("SubjectPublicKeyInfo: Unsupported algorithm.\n");
402 if (memcmp(j.data, id_dsa, 7) == 0)
404 if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_CONSTRUCTED
405 && asn1_der_decode_constructed_last(&j) == ASN1_ITERATOR_PRIMITIVE)
407 struct dsa_public_key pub;
409 dsa_public_key_init(&pub);
411 if (dsa_params_from_der_iterator(&pub, 0, &i)
412 && dsa_public_key_from_der_iterator(&pub, 0, &j))
414 nettle_buffer_reset(buffer);
415 res = dsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0;
419 werror("SubjectPublicKeyInfo: Invalid DSA key.\n");
424 if (memcmp(j.data, id_rsaEncryption, 9) == 0)
426 if (asn1_der_iterator_next(&j) == ASN1_ITERATOR_PRIMITIVE
427 && j.type == ASN1_NULL
429 && asn1_der_iterator_next(&j) == ASN1_ITERATOR_END)
431 struct rsa_public_key pub;
433 rsa_public_key_init(&pub);
435 if (rsa_public_key_from_der_iterator(&pub, 0, &i))
437 nettle_buffer_reset(buffer);
438 res = rsa_keypair_to_sexp(buffer, NULL, &pub, NULL) > 0;
442 werror("SubjectPublicKeyInfo: Invalid RSA key.\n");
449 werror("SubjectPublicKeyInfo: Invalid object.\n");
454 /* NOTE: Destroys contents of buffer */
455 /* Returns 1 on success, 0 on error, and -1 for unsupported algorithms. */
457 convert_type(struct nettle_buffer *buffer,
458 enum object_type type,
459 unsigned length, const uint8_t *data)
468 case GENERAL_PUBLIC_KEY:
469 res = convert_public_key(buffer, length, data);
473 res = convert_rsa_public_key(buffer, length, data);
476 case RSA_PRIVATE_KEY:
477 res = convert_rsa_private_key(buffer, length, data);
480 case DSA_PRIVATE_KEY:
481 res = convert_dsa_private_key(buffer, length, data);
486 res = write_file(buffer, stdout);
492 convert_file(struct nettle_buffer *buffer,
494 enum object_type type,
499 read_file(buffer, f);
500 if (base64 && !decode_base64(buffer, 0, &buffer->size))
503 if (convert_type(buffer, type,
504 buffer->size, buffer->contents) != 1)
514 struct pem_info info;
515 const uint8_t *marker;
517 nettle_buffer_reset(buffer);
518 switch (read_pem(buffer, f, &info))
529 if (!decode_base64(buffer, info.data_start, &info.data_length))
532 marker = buffer->contents + info.marker_start;
535 switch (info.marker_length)
538 if (memcmp(marker, "PUBLIC KEY", 10) == 0)
540 type = GENERAL_PUBLIC_KEY;
544 if (memcmp(marker, "RSA PUBLIC KEY", 14) == 0)
546 type = RSA_PUBLIC_KEY;
551 if (memcmp(marker, "RSA PRIVATE KEY", 15) == 0)
553 type = RSA_PRIVATE_KEY;
556 if (memcmp(marker, "DSA PRIVATE KEY", 15) == 0)
558 type = DSA_PRIVATE_KEY;
564 werror("Ignoring unsupported object type `%s'.\n", marker);
566 else if (convert_type(buffer, type,
568 buffer->contents + info.data_start) != 1)
576 main(int argc, char **argv)
578 struct nettle_buffer buffer;
579 enum object_type type = 0;
583 static const struct option options[] =
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' },
596 while ( (c = getopt_long(argc, argv, "V?b", options, NULL)) != -1)
607 case RSA_PRIVATE_KEY:
609 case DSA_PRIVATE_KEY:
610 case GENERAL_PUBLIC_KEY:
615 printf("FIXME: Usage information.\n");
619 printf("pkcs1-conv (" PACKAGE_STRING ")\n");
624 nettle_buffer_init_realloc(&buffer, NULL, nettle_xrealloc);
628 if (!convert_file(&buffer, stdin, type, base64))
634 const char *mode = (type || base64) ? "r" : "rb";
636 for (i = optind; i < argc; i++)
638 FILE *f = fopen(argv[i], mode);
640 die("Failed to open `%s': %s.\n", argv[i], strerror(errno));
642 if (!convert_file(&buffer, f, type, base64))