summaryrefslogtreecommitdiffstats
path: root/contrib/pkcs11-keygen/PEM_write_pubkey.c
blob: 65def632147d541150128919b47e53c009013554 (plain)
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);
}