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