2 * Copyright (C) 2011-2012 Juho Vähä-Herttua
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
23 #define RSAPRIVHEADER "-----BEGIN RSA PRIVATE KEY-----"
24 #define RSAPRIVFOOTER "-----END RSA PRIVATE KEY-----"
33 rsapem_init(const char *pemstr
)
35 rsapem_t
*rsapem
=NULL
;
42 header
= strstr(pemstr
, RSAPRIVHEADER
);
43 footer
= strstr(pemstr
, RSAPRIVFOOTER
);
44 if (!header
|| !footer
) {
49 /* Base64 decode the whole input excluding header and footer */
50 b64dec
= base64_init(NULL
, 0, 1);
51 datalen
= base64_decode(b64dec
, &data
, pemstr
+sizeof(RSAPRIVHEADER
),
52 (footer
-header
)-sizeof(RSAPRIVHEADER
));
53 base64_destroy(b64dec
);
63 printf("Decoded output:\n");
64 for (i
=0; i
<datalen
; i
++) {
65 printf("%02x", data
[i
]);
71 /* Check that first 4 bytes are all valid */
72 if (datalen
< 4 || data
[0] != 0x30 || data
[1] != 0x82) {
75 } else if (((data
[2] << 8) | data
[3]) != datalen
-4) {
80 rsapem
= calloc(1, sizeof(rsapem_t
));
86 /* Initialize the data */
88 rsapem
->datalen
= datalen
;
92 datalen
= rsapem_read_vector(rsapem
, &data
);
93 if (datalen
!= 1 && data
[0] != 0x00) {
95 rsapem_destroy(rsapem
);
103 rsapem_destroy(rsapem_t
*rsapem
)
112 rsapem_read_vector(rsapem_t
*rsapem
, unsigned char **data
)
117 if (rsapem
->datalen
-rsapem
->datapos
< 2) {
120 if (rsapem
->data
[rsapem
->datapos
] != 0x02) {
124 /* Read vector length */
125 length
= rsapem
->data
[rsapem
->datapos
+1];
126 if (length
<= 0x80) {
127 rsapem
->datapos
+= 2;
128 } else if (length
== 0x81) {
129 if (rsapem
->datalen
-rsapem
->datapos
< 3) {
132 length
= rsapem
->data
[rsapem
->datapos
+2];
133 rsapem
->datapos
+= 3;
134 } else if (length
== 0x82) {
135 if (rsapem
->datalen
-rsapem
->datapos
< 4) {
138 length
= (rsapem
->data
[rsapem
->datapos
+2] << 8) |
139 rsapem
->data
[rsapem
->datapos
+3];
140 rsapem
->datapos
+= 4;
145 /* Check that we have enough data available */
146 if (rsapem
->datalen
-rsapem
->datapos
< length
) {
150 /* Allocate data buffer and read bytes */
151 ptr
= malloc(length
);
155 memcpy(ptr
, rsapem
->data
+rsapem
->datapos
, length
);
156 rsapem
->datapos
+= length
;
158 /* Return buffer and length */