2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 print_int_text(const char *name
, const unsigned char *buf
, size_t len
)
39 printf("%s = ", name
);
40 for (u
= 0; u
< len
; u
++) {
41 printf("%02X", buf
[u
]);
47 print_int_C(const char *name
, const unsigned char *buf
, size_t len
)
51 printf("\nstatic const unsigned char %s[] = {", name
);
52 for (u
= 0; u
< len
; u
++) {
61 printf("0x%02X", buf
[u
]);
67 print_rsa(const br_rsa_private_key
*sk
, int print_text
, int print_C
)
70 print_int_text("p ", sk
->p
, sk
->plen
);
71 print_int_text("q ", sk
->q
, sk
->qlen
);
72 print_int_text("dp", sk
->dp
, sk
->dplen
);
73 print_int_text("dq", sk
->dq
, sk
->dqlen
);
74 print_int_text("iq", sk
->iq
, sk
->iqlen
);
77 print_int_C("RSA_P", sk
->p
, sk
->plen
);
78 print_int_C("RSA_Q", sk
->q
, sk
->qlen
);
79 print_int_C("RSA_DP", sk
->dp
, sk
->dplen
);
80 print_int_C("RSA_DQ", sk
->dq
, sk
->dqlen
);
81 print_int_C("RSA_IQ", sk
->iq
, sk
->iqlen
);
82 printf("\nstatic const br_rsa_private_key RSA = {\n");
83 printf("\t%lu,\n", (unsigned long)sk
->n_bitlen
);
84 printf("\t(unsigned char *)RSA_P, sizeof RSA_P,\n");
85 printf("\t(unsigned char *)RSA_Q, sizeof RSA_Q,\n");
86 printf("\t(unsigned char *)RSA_DP, sizeof RSA_DP,\n");
87 printf("\t(unsigned char *)RSA_DQ, sizeof RSA_DQ,\n");
88 printf("\t(unsigned char *)RSA_IQ, sizeof RSA_IQ\n");
94 print_ec(const br_ec_private_key
*sk
, int print_text
, int print_C
)
97 print_int_text("x", sk
->x
, sk
->xlen
);
100 print_int_C("EC_X", sk
->x
, sk
->xlen
);
101 printf("\nstatic const br_ec_private_key EC = {\n");
102 printf("\t%d,\n", sk
->curve
);
103 printf("\t(unsigned char *)EC_X, sizeof EC_X\n");
109 decode_key(const unsigned char *buf
, size_t len
, int print_text
, int print_C
)
111 br_skey_decoder_context dc
;
114 br_skey_decoder_init(&dc
);
115 br_skey_decoder_push(&dc
, buf
, len
);
116 err
= br_skey_decoder_last_error(&dc
);
118 const char *errname
, *errmsg
;
120 fprintf(stderr
, "ERROR (decoding): err=%d\n", err
);
121 errname
= find_error_name(err
, &errmsg
);
122 if (errname
!= NULL
) {
123 fprintf(stderr
, " %s: %s\n", errname
, errmsg
);
125 fprintf(stderr
, " (unknown)\n");
129 switch (br_skey_decoder_key_type(&dc
)) {
130 const br_rsa_private_key
*rk
;
131 const br_ec_private_key
*ek
;
134 rk
= br_skey_decoder_get_rsa(&dc
);
135 printf("RSA key (%lu bits)\n", (unsigned long)rk
->n_bitlen
);
136 print_rsa(rk
, print_text
, print_C
);
140 ek
= br_skey_decoder_get_ec(&dc
);
141 printf("EC key (curve = %d: %s)\n",
142 ek
->curve
, ec_curve_name(ek
->curve
));
143 print_ec(ek
, print_text
, print_C
);
147 fprintf(stderr
, "Unknown key type: %d\n",
148 br_skey_decoder_key_type(&dc
));
159 "usage: brssl skey [ options ] file...\n");
163 " -q suppress verbose messages\n");
165 " -text print public key details (human-readable)\n");
167 " -C print public key details (C code)\n");
172 do_skey(int argc
, char *argv
[])
177 int print_text
, print_C
;
189 for (i
= 0; i
< argc
; i
++) {
198 if (eqstr(arg
, "-v") || eqstr(arg
, "-verbose")) {
200 } else if (eqstr(arg
, "-q") || eqstr(arg
, "-quiet")) {
202 } else if (eqstr(arg
, "-text")) {
204 } else if (eqstr(arg
, "-C")) {
207 fprintf(stderr
, "ERROR: unknown option: '%s'\n", arg
);
209 goto skey_exit_error
;
212 if (num_files
== 0) {
213 fprintf(stderr
, "ERROR: no private key provided\n");
215 goto skey_exit_error
;
218 for (i
= 0; i
< argc
; i
++) {
225 buf
= read_file(fname
, &len
);
227 goto skey_exit_error
;
229 if (looks_like_DER(buf
, len
)) {
231 fprintf(stderr
, "File '%s': ASN.1/DER object\n",
234 if (decode_key(buf
, len
, print_text
, print_C
) < 0) {
235 goto skey_exit_error
;
241 fprintf(stderr
, "File '%s': decoding as PEM\n",
244 pos
= decode_pem(buf
, len
, &num
);
246 goto skey_exit_error
;
248 for (u
= 0; pos
[u
].name
; u
++) {
252 if (eqstr(name
, "RSA PRIVATE KEY")
253 || eqstr(name
, "EC PRIVATE KEY")
254 || eqstr(name
, "PRIVATE KEY"))
256 if (decode_key(pos
[u
].data
,
258 print_text
, print_C
) < 0)
260 goto skey_exit_error
;
270 for (u
= 0; pos
[u
].name
; u
++) {
271 free_pem_object_contents(&pos
[u
]);
281 * Release allocated structures.
288 for (u
= 0; pos
[u
].name
; u
++) {
289 free_pem_object_contents(&pos
[u
]);