1 | /*
|
---|
2 | * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <stdio.h>
|
---|
11 | #include <stdlib.h>
|
---|
12 | #include <openssl/pem.h>
|
---|
13 | #include <openssl/err.h>
|
---|
14 | #include <openssl/pkcs12.h>
|
---|
15 |
|
---|
16 | /* Simple PKCS#12 file reader */
|
---|
17 |
|
---|
18 | static char *find_friendly_name(PKCS12 *p12)
|
---|
19 | {
|
---|
20 | STACK_OF(PKCS7) *safes;
|
---|
21 | int n, m;
|
---|
22 | char *name = NULL;
|
---|
23 | PKCS7 *safe;
|
---|
24 | STACK_OF(PKCS12_SAFEBAG) *bags;
|
---|
25 | PKCS12_SAFEBAG *bag;
|
---|
26 |
|
---|
27 | if ((safes = PKCS12_unpack_authsafes(p12)) == NULL)
|
---|
28 | return NULL;
|
---|
29 |
|
---|
30 | for (n = 0; n < sk_PKCS7_num(safes) && name == NULL; n++) {
|
---|
31 | safe = sk_PKCS7_value(safes, n);
|
---|
32 | if (OBJ_obj2nid(safe->type) != NID_pkcs7_data
|
---|
33 | || (bags = PKCS12_unpack_p7data(safe)) == NULL)
|
---|
34 | continue;
|
---|
35 |
|
---|
36 | for (m = 0; m < sk_PKCS12_SAFEBAG_num(bags) && name == NULL; m++) {
|
---|
37 | bag = sk_PKCS12_SAFEBAG_value(bags, m);
|
---|
38 | name = PKCS12_get_friendlyname(bag);
|
---|
39 | }
|
---|
40 | sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
|
---|
41 | }
|
---|
42 |
|
---|
43 | sk_PKCS7_pop_free(safes, PKCS7_free);
|
---|
44 |
|
---|
45 | return name;
|
---|
46 | }
|
---|
47 |
|
---|
48 | int main(int argc, char **argv)
|
---|
49 | {
|
---|
50 | FILE *fp;
|
---|
51 | EVP_PKEY *pkey = NULL;
|
---|
52 | X509 *cert = NULL;
|
---|
53 | STACK_OF(X509) *ca = NULL;
|
---|
54 | PKCS12 *p12 = NULL;
|
---|
55 | char *name = NULL;
|
---|
56 | int i, ret = EXIT_FAILURE;
|
---|
57 |
|
---|
58 | if (argc != 4) {
|
---|
59 | fprintf(stderr, "Usage: pkread p12file password opfile\n");
|
---|
60 | exit(EXIT_FAILURE);
|
---|
61 | }
|
---|
62 |
|
---|
63 | if ((fp = fopen(argv[1], "rb")) == NULL) {
|
---|
64 | fprintf(stderr, "Error opening file %s\n", argv[1]);
|
---|
65 | exit(EXIT_FAILURE);
|
---|
66 | }
|
---|
67 | p12 = d2i_PKCS12_fp(fp, NULL);
|
---|
68 | fclose(fp);
|
---|
69 | if (p12 == NULL) {
|
---|
70 | fprintf(stderr, "Error reading PKCS#12 file\n");
|
---|
71 | ERR_print_errors_fp(stderr);
|
---|
72 | goto err;
|
---|
73 | }
|
---|
74 | if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
|
---|
75 | fprintf(stderr, "Error parsing PKCS#12 file\n");
|
---|
76 | ERR_print_errors_fp(stderr);
|
---|
77 | goto err;
|
---|
78 | }
|
---|
79 | name = find_friendly_name(p12);
|
---|
80 | PKCS12_free(p12);
|
---|
81 | if ((fp = fopen(argv[3], "w")) == NULL) {
|
---|
82 | fprintf(stderr, "Error opening file %s\n", argv[3]);
|
---|
83 | goto err;
|
---|
84 | }
|
---|
85 | if (name != NULL)
|
---|
86 | fprintf(fp, "***Friendly Name***\n%s\n", name);
|
---|
87 | if (pkey != NULL) {
|
---|
88 | fprintf(fp, "***Private Key***\n");
|
---|
89 | PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
|
---|
90 | }
|
---|
91 | if (cert != NULL) {
|
---|
92 | fprintf(fp, "***User Certificate***\n");
|
---|
93 | PEM_write_X509_AUX(fp, cert);
|
---|
94 | }
|
---|
95 | if (ca != NULL && sk_X509_num(ca) > 0) {
|
---|
96 | fprintf(fp, "***Other Certificates***\n");
|
---|
97 | for (i = 0; i < sk_X509_num(ca); i++)
|
---|
98 | PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
|
---|
99 | }
|
---|
100 | fclose(fp);
|
---|
101 |
|
---|
102 | ret = EXIT_SUCCESS;
|
---|
103 |
|
---|
104 | err:
|
---|
105 | OPENSSL_free(name);
|
---|
106 | X509_free(cert);
|
---|
107 | EVP_PKEY_free(pkey);
|
---|
108 | sk_X509_pop_free(ca, X509_free);
|
---|
109 |
|
---|
110 | return ret;
|
---|
111 | }
|
---|