summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-crypto/pktool/osslcommon.c
blob: 84b4fdbdcebd033c3c70bc515d6988b4ec4e3848 (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

/*
 * This file implements some "missing" routines that should
 * be part of the OpenSSL library but are not there yet.
 */

#include <cryptoutil.h>
#include "osslcommon.h"
#include <openssl/pkcs12.h>
#include <openssl/engine.h>

/*
 * OpenSSL usage needs algorithms (ciphers and digests), strings,
 * and engines loaded first to be useful.
 */
void
PKTOOL_setup_openssl(void)
{
	cryptodebug("inside PKTOOL_setup_openssl");

	/* Add all ciphers and digests. */
	OpenSSL_add_all_algorithms();

	/* Load up error message strings. */
	ERR_load_crypto_strings();

	/* Load up PKCS#11 engine. */
	/* ENGINE_load_pk11(); */

	/* Load up builtin crypto engines. */
	/*
	 * This function is actually defined in OpenSSL libcrypto
	 * library.  However it doesn't make its lint library correctly
	 * which is why this lint error occurs.  OpenSSL needs fixing.
	 * Do not put a LINTED comment here because lint will complain
	 * that the directive is ununsed.
	 */
	ENGINE_load_builtin_engines();

	/* U/I methods are not necessary here. */
	/* setup_ui_method(); */
}

/*
 * This should be an OpenSSL function, but they haven't added it yet.
 * See <openssl>/crypto/asn1/x_x509a.c:X509_alias_get0() for the model.
 */
unsigned char	*
PKTOOL_X509_keyid_get0(X509 *x, int *len)
{
	cryptodebug("inside PKTOOL_setup_openssl");

	if (x->aux == NULL || x->aux->keyid == NULL) {
		cryptodebug("certificate aux or aux->keyid is null");
		return (NULL);
	}
	if (len)
		*len = x->aux->keyid->length;
	return (x->aux->keyid->data);
}

/*
 * This should be an OpenSSL function, but couldn't find it yet.
 * It gets the subject name safely without dereferencing null pointers.
 * If it is ever found in OpenSSL, this should be removed and all
 * calls to it need to be replaced with right OpenSSL function.
 */
unsigned char	*
PKTOOL_X509_subject_name(X509 *x, int *len)
{
	X509_NAME	*temp;

	cryptodebug("inside PKTOOL_X509_subject_name");

	if ((temp = X509_get_subject_name(x)) == NULL) {
		cryptodebug("certificate subject name stack is null");
		return (NULL);
	}
	if (temp->bytes == NULL) {
		cryptodebug("certificate subject name stack bytes is null");
		return (NULL);
	}
	if (len)
		*len = temp->bytes->length;
	return ((unsigned char *)temp->bytes->data);
}

/*
 * This should be an OpenSSL function, but couldn't find it yet.
 * It gets the issuer name safely without dereferencing null pointers.
 * If it is ever found in OpenSSL, this should be removed and all
 * calls to it need to be replaced with right OpenSSL function.
 */
unsigned char	*
PKTOOL_X509_issuer_name(X509 *x, int *len)
{
	X509_NAME	*temp;

	cryptodebug("inside PKTOOL_X509_issuer_name");

	if ((temp = X509_get_issuer_name(x)) == NULL) {
		cryptodebug("certificate issuer name stack is null");
		return (NULL);
	}
	if (temp->bytes == NULL) {
		cryptodebug("certificate issuer name stack bytes is null");
		return (NULL);
	}
	if (len)
		*len = temp->bytes->length;
	return ((unsigned char *)temp->bytes->data);
}

/*
 * This should be an OpenSSL function, but couldn't find it yet.
 * It gets the serial number safely without dereferencing null pointers.
 * If it is ever found in OpenSSL, this should be removed and all
 * calls to it need to be replaced with right OpenSSL function.
 */
unsigned char	*
PKTOOL_X509_serial_number(X509 *x, int *len)
{
	ASN1_INTEGER	*temp;

	cryptodebug("inside PKTOOL_X509_serial_number");

	if ((temp = X509_get_serialNumber(x)) == NULL) {
		cryptodebug("certificate serial number is null");
		return (NULL);
	}
	if (len)
		*len = temp->length;
	return (temp->data);
}

/*
 * This should be an OpenSSL function, but couldn't find it yet.
 * It gets the cert value safely without dereferencing null pointers.
 * If it is ever found in OpenSSL, this should be removed and all
 * calls to it need to be replaced with right OpenSSL function.
 */
unsigned char	*
PKTOOL_X509_cert_value(X509 *x, int *len)
{
	PKCS12_SAFEBAG	*bag;

	cryptodebug("inside PKTOOL_X509_cert_value");

	if ((bag = PKCS12_x5092certbag(x)) == NULL) {
		cryptodebug("unable to convert cert to PKCS#12 bag");
		return (NULL);
	}
	if (bag->value.bag == NULL || bag->value.bag->value.x509cert == NULL) {
		cryptodebug("PKCS#12 bag value or cert inside it is null");
		return (NULL);
	}
	if (len)
		*len = bag->value.bag->value.x509cert->length;
	return (bag->value.bag->value.x509cert->data);
}

/*
 * Convert OpenSSL's ASN1_TIME format into a character buffer that
 * can then be converted into PKCS#11 format.  The buffer must be
 * at least 8 bytes long.  The length of the result will be 8 bytes.
 * Return value of 0 indicates failure, 1 indicates success.
 */
int
PKTOOL_cvt_ossltime(ASN1_TIME *t, char *buf)
{
	cryptodebug("inside PKTOOL_cvt_ossltime");

	if (t == NULL) {
		cryptodebug("time string is empty");
		buf[0] = '\0';
		return (0);
	}

	if (t->length == 15) {	/* generalized time: YYYYMMDDmmhhssZ */
		cryptodebug("time string is in generalized format");
		(void) snprintf(buf, 8, "%08.8s", t->data);
		return (1);
	}

	if (t->length == 13) {		/* UTC time: YYMMDDmmhhssZ */
		cryptodebug("time string is in UTC format");
		/* Guess whether its a 197x to 199x date, or a 20xx date. */
		(void) snprintf(buf, 8, "%s%06.6s",
		    ('7' <= t->data[0] && t->data[0] <= '9') ? "19" : "20",
		    t->data);
		return (1);
	}

	cryptodebug("time string is in unknown format");
	buf[0] = '\0';
	return (0);
}