1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/* OpenSSL tool
*
* usage: PEM_write_pubkey -e engine -p pin -k keyname -f filename
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/engine.h>
#include <openssl/conf.h>
#include <unistd.h>
#include <errno.h>
extern int PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x);
int
main(int argc, char *argv[])
{
ENGINE *e;
EVP_PKEY *pub_key;
FILE *fp;
char *engine = NULL;
char *pin = NULL;
char *keyname = NULL;
char *filename = NULL;
int c, errflg = 0;
extern char *optarg;
extern int optopt;
while ((c = getopt(argc, argv, ":e:p:k:f:")) != -1) {
switch (c) {
case 'e':
engine = optarg;
break;
case 'p':
pin = optarg;
break;
case 'k':
keyname = optarg;
break;
case 'f':
filename = optarg;
break;
case ':':
fprintf(stderr, "Option -%c requires an operand\n", optopt);
errflg++;
break;
case '?':
default:
fprintf(stderr, "Unrecognised option: -%c\n", optopt);
errflg++;
}
}
if ((errflg) || (!engine) || (!filename) || (!keyname)) {
fprintf(stderr,
"usage: PEM_write_pubkey -e engine [-p pin] "
"-k keyname -f filename\n");
exit(1);
}
/* Load the config file */
OPENSSL_config(NULL);
/* Register engine */
e = ENGINE_by_id(engine);
if (!e) {
/* the engine isn't available */
printf("The engine isn't available\n");
ERR_print_errors_fp(stderr);
exit(1);
}
/* Send PIN to engine */
if (pin && !ENGINE_ctrl_cmd_string(e, "PIN", pin, 0)){
printf("Error sending PIN to engine\n");
ERR_print_errors_fp(stderr);
ENGINE_free(e);
exit(1);
}
if (!ENGINE_init(e)) {
/* the engine couldn't initialise, release 'e' */
printf("The engine couldn't initialise\n");
ERR_print_errors_fp(stderr);
ENGINE_free(e);
exit(1);
}
if (!ENGINE_register_RSA(e)){
/* This should only happen when 'e' can't initialise, but the previous
* statement suggests it did. */
printf("This should not happen\n");
ERR_print_errors_fp(stderr);
exit(1);
}
/* Load public key */
pub_key = ENGINE_load_public_key(e, keyname, NULL, NULL);
if (pub_key == NULL) {
/* No public key */
printf("Error loading public key\n");
ERR_print_errors_fp(stderr);
ENGINE_free(e);
exit(1);
}
/* write public key to file in PEM format */
fp = fopen(filename, "w");
if (fp == NULL) {
printf("Error opening output file.\n");
ENGINE_free(e);
exit(1);
}
if (!PEM_write_PUBKEY(fp, pub_key)) {
/* Error writing public key */
printf("Error writing public key");
ERR_print_errors_fp(stderr);
ENGINE_free(e);
exit(1);
}
fclose(fp);
exit(0);
}
|