xref: /titanic_50/usr/src/common/net/wanboot/p12aux.h (revision 4eab410fb63816fe2c0ad0fd18b4c948613f6616)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2002, 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Copyright (c) 2015 by Delphix. All rights reserved.
29  */
30 
31 #ifndef	_P12AUX_H
32 #define	_P12AUX_H
33 
34 #include <openssl/pkcs12.h>
35 
36 #ifdef	__cplusplus
37 extern "C" {
38 #endif
39 
40 /*
41  * I really hate to do this.  It's pretty gross, but go ahead and use the
42  * macros and functions already defined to provide new EVP_PKEY-specific
43  * macros, for use within this file only.
44  *
45  * My apologies.
46  */
47 /* CSTYLED */
48 DECLARE_STACK_OF(EVP_PKEY)
49 
50 #define	sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
51 #define	sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
52 #define	sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
53 #define	sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
54 #define	sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
55 #define	sk_EVP_PKEY_find(st, val) SKM_sk_find(EVP_PKEY, (st), (val))
56 #define	sk_EVP_PKEY_delete(st, i) SKM_sk_delete(EVP_PKEY, (st), (i))
57 #define	sk_EVP_PKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY, (st), (ptr))
58 #define	sk_EVP_PKEY_insert(st, val, i) SKM_sk_insert(EVP_PKEY, (st), (val), (i))
59 #define	sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
60 	    (free_func))
61 #define	sk_EVP_PKEY_pop(st) SKM_sk_pop(EVP_PKEY, (st))
62 
63 /*
64  * This type indicates what to do with an attribute being returned.
65  */
66 typedef enum {
67 	GETDO_COPY = 1,		/* Simply return the value of the attribute */
68 	GETDO_DEL		/* Delete the attribute at the same time. */
69 } getdo_actions_t;
70 
71 /*
72  * The following is used to call the sunw_print_times function which is
73  * described at the bottom of the page.
74  */
75 typedef enum {
76 	PRNT_NOT_BEFORE = 1,	/* Print 'not before' date */
77 	PRNT_NOT_AFTER,		/* Print 'not after' date */
78 	PRNT_BOTH		/* Prints both dates */
79 } prnt_actions_t;
80 
81 /*
82  * For sunw_pkcs12_parse, the following are values for bits that indicate
83  * various types of searches/matching to do. Any of these values can be
84  * OR'd together. However, the order in which an attempt will be made
85  * to satisfy them is the order in which they are listed below. The
86  * exception is DO_NONE. It should not be OR'd with any other value.
87  */
88 #define	DO_NONE		0x00	/* Don't even try to match */
89 #define	DO_FIND_KEYID	0x01	/* 1st cert, key with matching localkeyid */
90 #define	DO_FIND_FN	0x02	/* 1st cert, key with matching friendlyname */
91 #define	DO_FIRST_PAIR	0x04	/* Return first matching cert/key pair found */
92 #define	DO_LAST_PAIR	0x08	/* Return last matching cert/key pair found */
93 #define	DO_UNMATCHING	0x10	/* Return first cert and/or key */
94 
95 /* Bits returned, which indicate what values were found. */
96 #define	FOUND_PKEY	0x01	/* Found one or more private key */
97 #define	FOUND_CERT	0x02	/* Found one or more client certificate */
98 #define	FOUND_CA_CERTS	0x04	/* Added at least one cert to the CA list */
99 #define	FOUND_XPKEY	0x08	/* Found at least one private key which does */
100 				/* not match a certificate in the certs list */
101 
102 /*
103  * sunw_cryto_init() does crypto-specific initialization.
104  *
105  * Arguments:
106  *   None.
107  *
108  * Returns:
109  *   None.
110  */
111 void sunw_crypto_init(void);
112 
113 /*
114  * sunw_PKCS12_parse() parses a pkcs#12 structure and returns component parts.
115  *
116  * Parse and decrypt a PKCS#12 structure returning user key, user cert and/or
117  * other (CA) certs. Note either ca should be NULL, *ca should be NULL,
118  * or it should point to a valid STACK_OF(X509) structure. pkey and cert can
119  * be passed uninitialized.
120  *
121  * Arguments:
122  *   p12      - Structure with pkcs12 info to be parsed
123  *   pass     - Pass phrase for the private key and entire pkcs12 wad (possibly
124  *              empty) or NULL if there is none.
125  *   matchty  - Info about which certs/keys to return if many are in the file.
126  *   keyid_str- If private key localkeyids are to match a predetermined value,
127  *              the value to match.
128  *   keyid_len- Length of the keyid byte string.
129  *   name_str - If friendlynames are to match a predetermined value, the value
130  *              to match.
131  *   pkey     - Points to location pointing to the private key returned.
132  *   cert     - Points to locaiton which points to the client cert returned
133  *   ca       - Points to location that points to a stack of 'certificate
134  *              authority' certs (possibly including trust anchors).
135  *
136  * Match based on the value of 'matchty' and the contents of 'keyid_str'
137  * and/or 'name_str', as appropriate.  Go through the lists of certs and
138  * private keys which were taken from the pkcs12 structure, looking for
139  * matches of the requested type.  This function only searches the lists of
140  * matching private keys and client certificates.  Kinds of matches allowed,
141  * and the order in which they will be checked, are:
142  *
143  *   1) Find the key and/or cert whose localkeyid attributes matches 'cmpstr'
144  *   2) Find the key and/or cert whose friendlyname attributes matches 'cmpstr'
145  *   3) Return the first matching key/cert pair found.
146  *   4) Return the last matching key/cert pair found.
147  *   5) Return whatever cert and/or key are available, even unmatching.
148  *
149  *   Append the certs which do not have matching private keys and which were
150  *   not selected to the CA list.
151  *
152  * If none of the bits are set, no client certs or private keys will be
153  * returned.  CA (aka trust anchor) certs can be.
154  *
155  * Notes: If #3 is selected, then #4 will never occur.  CA certs will be
156  * selected after a cert/key pairs are isolated.
157  *
158  * Returns:
159  *  <  0 - An error returned.  Call ERR_get_error() to get errors information.
160  *         Where possible, memory has been freed.
161  *  >= 0 - Objects were found and returned.  Which objects are indicated by
162  *         which bits are set (FOUND_PKEY, FOUND_CERT, FOUND_CA_CERTS).
163  */
164 int sunw_PKCS12_parse(PKCS12 *, const char *, int, char *, int, char *,
165     EVP_PKEY **, X509 **, STACK_OF(X509) **);
166 
167 
168 /*
169  * sunw_PKCS12_create() creates a pkcs#12 structure and given component parts.
170  *
171  * Given one or more of user private key, user cert and/or other (CA) certs,
172  * return an encrypted PKCS12 structure containing them.
173  *
174  * Arguments:
175  *   pass     - Pass phrase for the pkcs12 structure and private key (possibly
176  *              empty) or NULL if there is none.  It will be used to encrypt
177  *              both the private key(s) and as the pass phrase for the whole
178  *              pkcs12 wad.
179  *   pkey     - Points to stack of private keys.
180  *   cert     - Points to stack of client (public ke) certs
181  *   ca       - Points to stack of 'certificate authority' certs (or trust
182  *              anchors).
183  *
184  *   Note that any of these may be NULL.
185  *
186  * Returns:
187  *   NULL     - An error occurred.
188  *   != NULL  - Address of PKCS12 structure.  The user is responsible for
189  *              freeing the memory when done.
190  */
191 PKCS12 *sunw_PKCS12_create(const char *, STACK_OF(EVP_PKEY) *, STACK_OF(X509) *,
192     STACK_OF(X509) *);
193 
194 
195 /*
196  * sunw_split_certs() - Given a list of certs and a list of private keys,
197  *     moves certs which match one of the keys to a different stack.
198  *
199  * Arguments:
200  *   allkeys  - Points to a stack of private keys to search.
201  *   allcerts - Points to a stack of certs to be searched.
202  *   keycerts - Points to address of a stack of certs with matching private
203  *              keys.  They are moved from 'allcerts'.  This may not be NULL
204  *              when called.  If *keycerts is NULL upon entry, a new stack will
205  *              be allocated.  Otherwise, it must be a valid STACK_OF(509).
206  *   nocerts  - Points to address of a stack for keys which have no matching
207  *              certs.  Keys are moved from 'allkeys' here when they have no
208  *              matching certs.  If this is NULL, matchless keys will be
209  *              discarded.
210  *
211  *   Notes:  If an error occurs while moving certs, the cert being move may be
212  *   lost.  'keycerts' may only contain part of the matching certs.  The number
213  *   of certs successfully moved can be found by checking sk_X509_num(keycerts).
214  *
215  *   If there is a key which does not have a matching cert, it is moved to
216  *   the list nocerts.
217  *
218  *   If all certs are removed from 'certs' and/or 'pkeys', it will be the
219  *   caller's responsibility to free the empty stacks.
220  *
221  * Returns:
222  *  <  0 - An error returned.  Call ERR_get_error() to get errors information.
223  *         Where possible, memory has been freed.
224  *  >= 0 - The number of certs moved from 'cert' to 'pkcerts'.
225  */
226 int sunw_split_certs(STACK_OF(EVP_PKEY) *, STACK_OF(X509) *, STACK_OF(X509) **,
227     STACK_OF(EVP_PKEY) **);
228 
229 /*
230  * sunw_evp_pkey_free() Given an EVP_PKEY structure, free any attributes
231  *     that are attached.  Then free the EVP_PKEY itself.
232  *
233  *     This is the replacement for EVP_PKEY_free() for the sunw stuff.
234  *     It should be used in places where EVP_PKEY_free would be used,
235  *     including calls to sk_EVP_PKEY_pop_free().
236  *
237  * Arguments:
238  *   pkey     - Entry which potentially has attributes to be freed.
239  *
240  * Returns:
241  *   None.
242  */
243 void sunw_evp_pkey_free(EVP_PKEY *);
244 
245 /*
246  * sunw_set_localkeyid() sets the localkeyid in a cert, a private key or
247  *     both.  Any existing localkeyid will be discarded.
248  *
249  * Arguments:
250  *   keyid_str- A byte string with the localkeyid to set
251  *   keyid_len- Length of the keyid byte string.
252  *   pkey     - Points to a private key to set the keyidstr in.
253  *   cert     - Points to a cert to set the keyidstr in.
254  *
255  * Note that setting a keyid into a cert which will not be written out as
256  * a PKCS12 cert is pointless since it will be lost.
257  *
258  * Returns:
259  *   0        - Success.
260  *   < 0      - An error occurred.  It was probably an error in allocating
261  *              memory.  The error will be set in the error stack.  Call
262  *              ERR_get_error() to get specific information.
263  */
264 int sunw_set_localkeyid(const char *, int, EVP_PKEY *, X509 *);
265 
266 
267 /*
268  * sunw_get_pkey_localkeyid() gets the localkeyid from a private key.  It can
269  *     optionally remove the value found.
270  *
271  * Arguments:
272  *   dowhat   - What to do with the attributes (remove them or copy them).
273  *   pkey     - Points to a private key to set the keyidstr in.
274  *   keyid_str- Points to a location which will receive the pointer to
275  *              a byte string containing the binary localkeyid.  Note that
276  *              this is a copy, and the caller must free it.
277  *   keyid_len- Length of keyid_str.
278  *
279  * Returns:
280  *   >= 0     - The number of characters in the keyid returned.
281  *   < 0      - An error occurred.  It was probably an error in allocating
282  *              memory.  The error will be set in the error stack.  Call
283  *              ERR_get_error() to get specific information.
284  */
285 int sunw_get_pkey_localkeyid(getdo_actions_t, EVP_PKEY *, char **, int *);
286 
287 
288 /*
289  * sunw_get_pkey_fname() gets the friendlyName from a private key.  It can
290  *     optionally remove the value found.
291  *
292  * Arguments:
293  *   dowhat   - What to do with the attributes (remove them or just return
294  *              them).
295  *   pkey     - Points to a private key to get the keyid from
296  *   fname    - Points to a location which will receive the pointer to a
297  *              byte string with the ASCII friendlyname
298  *
299  * Returns:
300  *   >= 0     - The number of characters in the keyid returned.
301  *   < 0      - An error occurred.  It was probably an error in allocating
302  *              memory.  The error will be set in the error stack.  Call
303  *              ERR_get_error() to get specific information.
304  */
305 int sunw_get_pkey_fname(getdo_actions_t, EVP_PKEY *, char **);
306 
307 
308 /*
309  * sunw_find_localkeyid() searches stacks of certs and private keys, and
310  *     returns the first matching cert/private key found.
311  *
312  * Look for a keyid in a stack of certs.  if 'certs' is NULL and 'pkeys' is
313  * not NULL, search the list of private keys.  Move the matching cert to
314  * 'matching_cert' and its matching private key to 'matching_pkey'.  If no
315  * cert or keys match, no match occurred.
316  *
317  * Arguments:
318  *   keyid_str- A byte string with the localkeyid to match
319  *   keyid_len- Length of the keyid byte string.
320  *   pkeys    - Points to a stack of private keys which match the certs.
321  *              This may be NULL, in which case no keys are returned.
322  *   certs    - Points to a stack of certs to search.  If NULL, search the
323  *              stack of keys instead.
324  *   matching_pkey
325  *            - Pointer to receive address of first matching pkey found.
326  *              'matching_pkey' must not be NULL; '*matching_pkey' will be
327  *              reset.
328  *   matching_cert
329  *            - Pointer to receive address of first matching cert found.
330  *              'matching_cert' must not be NULL; '*matching_cert' will be
331  *              reset.
332  *
333  * Returns:
334  *  <  0 - An error returned.  Call ERR_get_error() to get errors information.
335  *         Where possible, memory has been freed.
336  *  >= 0 - Objects were found and returned.  Which objects are indicated by
337  *         which bits are set (FOUND_PKEY and/or FOUND_CERT).
338  */
339 int sunw_find_localkeyid(char *, int, STACK_OF(EVP_PKEY) *, STACK_OF(X509) *,
340     EVP_PKEY **, X509 **);
341 
342 
343 /*
344  * sunw_find_fname() searches stacks of certs and private keys for one with
345  *     a matching friendlyname and returns the first matching cert/private
346  *     key found.
347  *
348  * Look for a friendlyname in a stack of certs.  if 'certs' is NULL and 'pkeys'
349  * is not NULL, search the list of private keys.  Move the matching cert to
350  * 'matching_cert' and its matching private key to 'matching_pkey'.  If no
351  * cert or keys match, no match occurred.
352  *
353  * Arguments:
354  *   fname    - Friendlyname to find (NULL-terminated ASCII string).
355  *   pkeys    - Points to a stack of private keys which match the certs.
356  *              This may be NULL, in which case no keys are returned.
357  *   certs    - Points to a stack of certs to search.  If NULL, search the
358  *              stack of keys instead.
359  *   matching_pkey
360  *            - Pointer to receive address of first matching pkey found.
361  *   matching_cert
362  *            - Pointer to receive address of first matching cert found.
363  *
364  * Returns:
365  *  <  0 - An error returned.  Call ERR_get_error() to get errors information.
366  *         Where possible, memory has been freed.
367  *  >= 0 - Objects were found and returned.  Which objects are indicated by
368  *         which bits are set (FOUND_PKEY and/or FOUND_CERT).
369  */
370 int sunw_find_fname(char *, STACK_OF(EVP_PKEY) *, STACK_OF(X509) *, EVP_PKEY **,
371     X509 **);
372 
373 
374 /*
375  * sunw_print_times() formats and prints cert times to the given file.
376  *
377  * The label is printed on one line. One or both dates are printed on
378  * the following line or two, each with it's own indented label in the
379  * format:
380  *
381  *    label
382  *      'not before' date: whatever
383  *      'not after' date:  whatever
384  *
385  * Arguments:
386  *   fp       - file pointer for file to write to.
387  *   dowhat   - what field(s) to print.
388  *   label    - Label to use.  If NULL, no line will be printed.
389  *   cert     - Points to a client or CA cert to check
390  *
391  * Returns:
392  *  <  0 - An error occured.
393  *  >= 0 - Number of lines written.
394  */
395 int sunw_print_times(FILE *, prnt_actions_t, char *, X509 *);
396 
397 
398 /*
399  * sunw_check_keys() compares the public key in the certificate and a
400  *     private key to ensure that they match.
401  *
402  * Arguments:
403  *   cert     - Points to a certificate.
404  *   pkey     - Points to a private key.
405  *
406  * Returns:
407  *  == 0 - These do not match.
408  *  != 0 - The cert's public key and the private key match.
409  */
410 int sunw_check_keys(X509 *, EVP_PKEY *);
411 
412 
413 /*
414  * sunw_issuer_attrs - Given a cert, return the issuer-specific attributes
415  *     as one ASCII string.
416  *
417  * Arguments:
418  *   cert     - Cert to process
419  *   buf      - If non-NULL, buffer to receive string.  If NULL, one will
420  *              be allocated and its value will be returned to the caller.
421  *   len      - If 'buff' is non-null, the buffer's length.
422  *
423  * This returns an ASCII string with all issuer-related attributes in one
424  * string separated by '/' characters.  Each attribute begins with its name
425  * and an equal sign.  Two attributes (ATTR1 and Attr2) would have the
426  * following form:
427  *
428  *         ATTR1=attr_value/ATTR2=attr2_value
429  *
430  * Returns:
431  *   != NULL  - Pointer to the ASCII string containing the issuer-related
432  *              attributes.  If the 'buf' argument was NULL, this is a
433  *              dynamically-allocated buffer and the caller will have the
434  *              responsibility for freeing it.
435  *   NULL     - Memory needed to be allocated but could not be.  Errors
436  *              are set on the error stack.
437  */
438 char *sunw_issuer_attrs(X509 *cert, char *buf, int len);
439 
440 
441 /*
442  * sunw_subject_attrs - Given a cert, return the subject-specific attributes
443  *     as one ASCII string.
444  *
445  * Arguments:
446  *   cert     - Cert to process
447  *   buf      - If non-NULL, buffer to receive string.  If NULL, one will
448  *              be allocated and its value will be returned to the caller.
449  *   len      - If 'buff' is non-null, the buffer's length.
450  *
451  * This returns an ASCII string with all subject-related attributes in one
452  * string separated by '/' characters.  Each attribute begins with its name
453  * and an equal sign.  Two attributes (ATTR1 and Attr2) would have the
454  * following form:
455  *
456  *         ATTR1=attr_value/ATTR2=attr2_value
457  *
458  * Returns:
459  *   != NULL  - Pointer to the ASCII string containing the subject-related
460  *              attributes.  If the 'buf' argument was NULL, this is a
461  *              dynamically-allocated buffer and the caller will have the
462  *              responsibility for freeing it.
463  *   NULL     - Memory needed to be allocated but could not be.  Errors
464  *              are set on the error stack.
465  */
466 char *sunw_subject_attrs(X509 *cert, char *buf, int len);
467 
468 /*
469  * sunw_append_keys - Given two stacks of private keys, remove the keys from
470  *      the second stack and append them to the first.  Both stacks must exist
471  *      at time of call.
472  *
473  * Arguments:
474  *   dst 	- the stack to receive the keys from 'src'
475  *   src	- the stack whose keys are to be moved.
476  *
477  * Returns:
478  *   -1  	- An error occurred.  The error status is set.
479  *   >= 0       - The number of keys that were copied.
480  */
481 int sunw_append_keys(STACK_OF(EVP_PKEY) *, STACK_OF(EVP_PKEY) *);
482 
483 
484 #ifdef	__cplusplus
485 }
486 #endif
487 
488 #endif	/* _P12AUX_H */
489