4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include <sys/types.h>
41 #include <cryptoutil.h>
44 #include <sys/crypto/elfsign.h>
45 #include <libelfsign.h>
49 const char _PATH_ELFSIGN_CRYPTO_CERTS
[] = CRYPTO_CERTS_DIR
;
50 const char _PATH_ELFSIGN_ETC_CERTS
[] = ETC_CERTS_DIR
;
53 * The CACERT and OBJCACERT are the Cryptographic Trust Anchors
54 * for the Solaris Cryptographic Framework.
56 * The SECACERT is the Signed Execution Trust Anchor that the
57 * Cryptographic Framework uses for FIPS-140 validation of non-crypto
60 static const char _PATH_CRYPTO_CACERT
[] = CRYPTO_CERTS_DIR
"/CA";
61 static const char _PATH_CRYPTO_OBJCACERT
[] = CRYPTO_CERTS_DIR
"/SUNWObjectCA";
62 static const char _PATH_CRYPTO_SECACERT
[] = ETC_CERTS_DIR
"/SUNWSolarisCA";
63 static ELFCert_t CACERT
= NULL
;
64 static ELFCert_t OBJCACERT
= NULL
;
65 static ELFCert_t SECACERT
= NULL
;
66 static pthread_mutex_t ca_mutex
= PTHREAD_MUTEX_INITIALIZER
;
68 static void elfcertlib_freecert(ELFsign_t
, ELFCert_t
);
69 static ELFCert_t
elfcertlib_allocatecert(void);
72 * elfcertlib_verifycert - Verify the Cert with a Trust Anchor
74 * IN ess - elfsign context structure
79 * We first setup the Trust Anchor (CA and SUNWObjectCA) certs
80 * if it hasn't been done already. We verify that the files on disk
81 * are those we expected.
83 * We then verify the given cert using the publickey of a TA.
84 * If the passed in cert is a TA or it has been verified already we
85 * short cut and return TRUE without futher validation.
89 elfcertlib_verifycert(ELFsign_t ess
, ELFCert_t cert
)
91 KMF_ATTRIBUTE attrlist
[8];
95 if ((cert
->c_verified
== E_OK
) || (cert
->c_verified
== E_IS_TA
)) {
99 (void) pthread_mutex_lock(&ca_mutex
);
100 if (CACERT
== NULL
) {
101 (void) elfcertlib_getcert(ess
, (char *)_PATH_CRYPTO_CACERT
,
102 NULL
, &CACERT
, ES_GET
);
105 if (OBJCACERT
== NULL
) {
106 (void) elfcertlib_getcert(ess
, (char *)_PATH_CRYPTO_OBJCACERT
,
107 NULL
, &OBJCACERT
, ES_GET
);
110 if (SECACERT
== NULL
) {
111 (void) elfcertlib_getcert(ess
,
112 (char *)_PATH_CRYPTO_SECACERT
, NULL
, &SECACERT
,
116 (void) pthread_mutex_unlock(&ca_mutex
);
118 if (CACERT
!= NULL
) {
120 kmf_set_attr_at_index(attrlist
, numattr
++,
121 KMF_CERT_DATA_ATTR
, &cert
->c_cert
.certificate
,
123 kmf_set_attr_at_index(attrlist
, numattr
++,
124 KMF_SIGNER_CERT_DATA_ATTR
, &CACERT
->c_cert
.certificate
,
127 rv
= kmf_verify_cert(ess
->es_kmfhandle
, numattr
, attrlist
);
129 if (ess
->es_certCAcallback
!= NULL
)
130 (ess
->es_certvercallback
)(ess
->es_callbackctx
,
132 cert
->c_verified
= E_OK
;
137 if (OBJCACERT
!= NULL
) {
139 kmf_set_attr_at_index(attrlist
, numattr
++,
140 KMF_CERT_DATA_ATTR
, &cert
->c_cert
.certificate
,
142 kmf_set_attr_at_index(attrlist
, numattr
++,
143 KMF_SIGNER_CERT_DATA_ATTR
, &OBJCACERT
->c_cert
.certificate
,
146 rv
= kmf_verify_cert(ess
->es_kmfhandle
, numattr
, attrlist
);
148 if (ess
->es_certCAcallback
!= NULL
)
149 (ess
->es_certvercallback
)(ess
->es_callbackctx
,
151 cert
->c_verified
= E_OK
;
156 if (SECACERT
!= NULL
) {
158 kmf_set_attr_at_index(attrlist
, numattr
++,
159 KMF_CERT_DATA_ATTR
, &cert
->c_cert
.certificate
,
161 kmf_set_attr_at_index(attrlist
, numattr
++,
162 KMF_SIGNER_CERT_DATA_ATTR
, &SECACERT
->c_cert
.certificate
,
165 rv
= kmf_verify_cert(ess
->es_kmfhandle
, numattr
, attrlist
);
167 if (ess
->es_certCAcallback
!= NULL
)
168 (ess
->es_certvercallback
)(ess
->es_callbackctx
,
170 cert
->c_verified
= E_OK
;
179 * elfcertlib_getcert - Get the certificate for signer_DN
181 * IN ess - elfsign context structure
182 * cert_pathname - path to cert (May be NULL)
183 * signer_DN - The DN we are looking for (May be NULL)
184 * action - indicates crypto verification call
185 * OUT certp - allocated/loaded ELFCert_t
187 * If the cert_pathname is passed use it and don't search.
188 * Otherwise, go looking in certificate directories
191 elfcertlib_getcert(ELFsign_t ess
, char *cert_pathname
,
192 char *signer_DN
, ELFCert_t
*certp
, enum ES_ACTION action
)
195 ELFCert_t cert
= NULL
;
196 KMF_X509_DER_CERT certbuf
[2];
198 boolean_t ret
= B_FALSE
;
199 char *pathlist
[3], **plp
;
201 cryptodebug("elfcertlib_getcert: path=%s, DN=%s",
202 cert_pathname
? cert_pathname
: "-none-",
203 signer_DN
? signer_DN
: "-none-");
205 if (cert_pathname
== NULL
&& signer_DN
== NULL
) {
206 cryptodebug("elfcertlib_getcert: lack of specificity");
211 if (cert_pathname
!= NULL
) {
212 /* look in the specified object */
213 *plp
++ = cert_pathname
;
215 /* look in the certificate directories */
216 *plp
++ = (char *)_PATH_ELFSIGN_CRYPTO_CERTS
;
218 * crypto verifications don't search beyond
219 * _PATH_ELFSIGN_CRYPTO_CERTS
221 if (action
!= ES_GET_CRYPTO
)
222 *plp
++ = (char *)_PATH_ELFSIGN_ETC_CERTS
;
226 if ((cert
= elfcertlib_allocatecert()) == NULL
) {
230 for (plp
= pathlist
; *plp
; plp
++) {
231 KMF_ATTRIBUTE attrlist
[8];
232 KMF_KEYSTORE_TYPE kstype
;
233 KMF_CERT_VALIDITY certvalidity
;
236 kstype
= KMF_KEYSTORE_OPENSSL
;
237 certvalidity
= KMF_ALL_CERTS
;
241 kmf_set_attr_at_index(attrlist
, numattr
++,
242 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
243 kmf_set_attr_at_index(attrlist
, numattr
++,
244 KMF_X509_DER_CERT_ATTR
, certbuf
,
245 sizeof (KMF_X509_DER_CERT
));
246 kmf_set_attr_at_index(attrlist
, numattr
++,
247 KMF_COUNT_ATTR
, &ncerts
, sizeof (uint32_t));
248 if (signer_DN
!= NULL
) {
249 kmf_set_attr_at_index(attrlist
, numattr
++,
250 KMF_SUBJECT_NAME_ATTR
, signer_DN
,
253 kmf_set_attr_at_index(attrlist
, numattr
++,
254 KMF_CERT_VALIDITY_ATTR
, &certvalidity
,
255 sizeof (KMF_CERT_VALIDITY
));
256 kmf_set_attr_at_index(attrlist
, numattr
++,
257 KMF_CERT_FILENAME_ATTR
, *plp
, strlen (*plp
));
259 rv
= kmf_find_cert(ess
->es_kmfhandle
, numattr
, attrlist
);
264 cert
->c_cert
= certbuf
[0];
266 /* release any extras */
267 kmf_free_kmf_cert(ess
->es_kmfhandle
, &certbuf
[1]);
268 if (signer_DN
== NULL
) {
269 /* There can be only one */
270 cryptodebug("elfcertlib_getcert: "
271 "too many certificates found in %s",
276 /* cache subject and issuer */
277 rv
= kmf_get_cert_subject_str(ess
->es_kmfhandle
,
278 &cert
->c_cert
.certificate
, &cert
->c_subject
);
282 rv
= kmf_get_cert_issuer_str(ess
->es_kmfhandle
,
283 &cert
->c_cert
.certificate
, &cert
->c_issuer
);
289 cryptodebug("elfcertlib_getcert: no certificate found");
293 cert
->c_verified
= E_UNCHECKED
;
296 * If the cert we are loading is the trust anchor (ie the CA) then
297 * we mark it as such in cert. This is so that we don't attempt
298 * to verify it later. The CA is always implicitly verified.
300 if (cert_pathname
!= NULL
&& (
301 strcmp(cert_pathname
, _PATH_CRYPTO_CACERT
) == 0 ||
302 strcmp(cert_pathname
, _PATH_CRYPTO_OBJCACERT
) == 0 ||
303 strcmp(cert_pathname
, _PATH_CRYPTO_SECACERT
) == 0)) {
304 if (ess
->es_certCAcallback
!= NULL
)
305 (ess
->es_certCAcallback
)(ess
->es_callbackctx
, cert
,
307 cert
->c_verified
= E_IS_TA
;
317 elfcertlib_freecert(ess
, cert
);
318 if (signer_DN
!= NULL
)
319 cryptoerror(LOG_ERR
, "unable to find a certificate "
320 "for DN: %s", signer_DN
);
322 cryptoerror(LOG_ERR
, "unable to load certificate "
323 "from %s", cert_pathname
);
329 * elfcertlib_loadprivatekey - Load the private key from path
331 * IN ess - elfsign context structure
338 elfcertlib_loadprivatekey(ELFsign_t ess
, ELFCert_t cert
, const char *pathname
)
340 KMF_RETURN rv
= KMF_OK
;
341 KMF_KEY_HANDLE keybuf
[2];
342 KMF_ATTRIBUTE attrlist
[16];
344 KMF_KEYSTORE_TYPE kstype
;
346 KMF_KEY_CLASS keyclass
;
347 KMF_ENCODE_FORMAT format
;
350 kstype
= KMF_KEYSTORE_OPENSSL
;
352 keytype
= KMF_KEYALG_NONE
;
353 keyclass
= KMF_ASYM_PRI
;
354 format
= KMF_FORMAT_UNDEF
;
357 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEYSTORE_TYPE_ATTR
,
358 &kstype
, sizeof (kstype
));
359 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEY_HANDLE_ATTR
,
360 keybuf
, sizeof (KMF_KEY_HANDLE
));
361 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_COUNT_ATTR
,
362 &nkeys
, sizeof (uint32_t));
363 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEYALG_ATTR
,
364 &keytype
, sizeof (keytype
));
365 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEYCLASS_ATTR
,
366 &keyclass
, sizeof (keyclass
));
367 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_ENCODE_FORMAT_ATTR
,
368 &format
, sizeof (format
));
369 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEY_FILENAME_ATTR
,
370 (char *)pathname
, strlen(pathname
));
372 rv
= kmf_find_key(ess
->es_kmfhandle
, numattr
, attrlist
);
376 /* lack of specificity */
377 cryptodebug("found %d keys at %s", nkeys
, pathname
);
380 cert
->c_privatekey
= keybuf
[0];
381 cryptodebug("key %s loaded", pathname
);
386 * elfcertlib_loadtokenkey - Load the private key from token
388 * IN ess - elfsign context structure
396 elfcertlib_loadtokenkey(ELFsign_t ess
, ELFCert_t cert
,
397 const char *token_label
, const char *pin
)
402 KMF_ATTRIBUTE attrlist
[16];
404 KMF_KEYSTORE_TYPE kstype
;
406 KMF_KEY_CLASS keyclass
;
407 KMF_ENCODE_FORMAT format
;
408 KMF_CREDENTIAL pincred
;
409 boolean_t tokenbool
, privatebool
;
413 * We will search for the key based on the ID attribute
414 * which was added when the key was created. ID is
415 * a SHA-1 hash of the public modulus shared by the
416 * key and the certificate.
418 rv
= kmf_get_cert_id_str(&cert
->c_cert
.certificate
, &idstr
);
420 (void) kmf_get_kmf_error_str(rv
, &kmferr
);
421 cryptodebug("Error getting ID from cert: %s\n",
422 (kmferr
? kmferr
: "Unrecognized KMF error"));
427 kstype
= KMF_KEYSTORE_PK11TOKEN
;
429 keytype
= KMF_KEYALG_NONE
;
430 keyclass
= KMF_ASYM_PRI
;
431 format
= KMF_FORMAT_UNDEF
;
432 pincred
.cred
= (char *)pin
;
433 pincred
.credlen
= strlen(pin
);
435 privatebool
= B_TRUE
;
438 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEYSTORE_TYPE_ATTR
,
439 &kstype
, sizeof (kstype
));
440 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEY_HANDLE_ATTR
,
441 &cert
->c_privatekey
, sizeof (KMF_KEY_HANDLE
));
442 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_COUNT_ATTR
,
443 &nkeys
, sizeof (uint32_t));
444 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEYALG_ATTR
,
445 &keytype
, sizeof (keytype
));
446 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEYCLASS_ATTR
,
447 &keyclass
, sizeof (keyclass
));
448 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_ENCODE_FORMAT_ATTR
,
449 &format
, sizeof (format
));
450 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_IDSTR_ATTR
,
451 idstr
, strlen(idstr
));
452 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_CREDENTIAL_ATTR
,
453 &pincred
, sizeof (KMF_CREDENTIAL
));
454 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_TOKEN_BOOL_ATTR
,
455 &tokenbool
, sizeof (tokenbool
));
456 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_PRIVATE_BOOL_ATTR
,
457 &privatebool
, sizeof (privatebool
));
459 rv
= kmf_find_key(ess
->es_kmfhandle
, numattr
, attrlist
);
462 (void) kmf_get_kmf_error_str(rv
, &kmferr
);
463 cryptodebug("Error finding private key: %s\n",
464 (kmferr
? kmferr
: "Unrecognized KMF error"));
469 cryptodebug("Error finding private key: No key found\n");
472 cryptodebug("key found in %s", token_label
);
473 cryptodebug("elfcertlib_loadprivatekey = 0x%.8X",
474 &cert
->c_privatekey
);
479 static const CK_BYTE MD5_DER_PREFIX
[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
480 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
483 * elfcertlib_sign - sign the given DATA using the privatekey in cert
485 * IN ess - elfsign context structure
489 * OUT sig - must be big enough to hold the signature of data
490 * Caller must allocate
491 * sig_len - actual length used; 0 on failure.
496 elfcertlib_sign(ELFsign_t ess
, ELFCert_t cert
,
497 const uchar_t
*data
, size_t data_len
,
498 uchar_t
*sig
, size_t *sig_len
)
503 uchar_t der_data
[sizeof (MD5_DER_PREFIX
) + MD5_DIGEST_LENGTH
];
504 KMF_ATTRIBUTE attrlist
[8];
507 if (ess
->es_version
<= FILESIG_VERSION2
) {
508 /* compatibility: take MD5 hash of SHA1 hash */
509 size_t derlen
= MD5_DIGEST_LENGTH
;
513 * first: digest using software-based methods, don't
514 * rely on the token for hashing.
517 MD5Update(&ctx
, data
, data_len
);
518 MD5Final(&der_data
[sizeof (MD5_DER_PREFIX
)], &ctx
);
521 * second: insert prefix
523 (void) memcpy(der_data
, MD5_DER_PREFIX
,
524 sizeof (MD5_DER_PREFIX
));
526 * prepare to sign the local buffer
528 tobesigned
.Data
= (uchar_t
*)der_data
;
529 tobesigned
.Length
= sizeof (MD5_DER_PREFIX
) + derlen
;
531 tobesigned
.Data
= (uchar_t
*)data
;
532 tobesigned
.Length
= data_len
;
535 signature
.Data
= (uchar_t
*)sig
;
536 signature
.Length
= *sig_len
;
539 kmf_set_attr_at_index(attrlist
, numattr
++,
540 KMF_KEYSTORE_TYPE_ATTR
, &(cert
->c_privatekey
.kstype
),
541 sizeof (KMF_KEYSTORE_TYPE
));
542 kmf_set_attr_at_index(attrlist
, numattr
++,
543 KMF_KEY_HANDLE_ATTR
, &cert
->c_privatekey
, sizeof (KMF_KEY_HANDLE
));
544 kmf_set_attr_at_index(attrlist
, numattr
++,
545 KMF_OID_ATTR
, (KMF_OID
*)&KMFOID_RSA
, sizeof (KMF_OID
));
546 kmf_set_attr_at_index(attrlist
, numattr
++,
547 KMF_DATA_ATTR
, &tobesigned
, sizeof (KMF_DATA
));
548 kmf_set_attr_at_index(attrlist
, numattr
++,
549 KMF_OUT_DATA_ATTR
, &signature
, sizeof (KMF_DATA
));
551 ret
= kmf_sign_data(ess
->es_kmfhandle
, numattr
, attrlist
);
556 (void) kmf_get_kmf_error_str(ret
, &kmferr
);
557 cryptodebug("Error signing data: %s\n",
558 (kmferr
? kmferr
: "Unrecognized KMF error"));
563 *sig_len
= signature
.Length
;
568 * elfcertlib_verifysig - verify the given DATA using the public key in cert
570 * IN ess - elfsign context structure
580 elfcertlib_verifysig(ELFsign_t ess
, ELFCert_t cert
,
581 const uchar_t
*signature
, size_t sig_len
,
582 const uchar_t
*data
, size_t data_len
)
587 KMF_ALGORITHM_INDEX algid
;
588 KMF_ATTRIBUTE attrlist
[8];
589 KMF_KEYSTORE_TYPE kstype
;
592 indata
.Data
= (uchar_t
*)data
;
593 indata
.Length
= data_len
;
594 insig
.Data
= (uchar_t
*)signature
;
595 insig
.Length
= sig_len
;
597 if (ess
->es_version
<= FILESIG_VERSION2
)
598 algid
= KMF_ALGID_MD5WithRSA
;
600 algid
= KMF_ALGID_RSA
;
603 * We tell KMF to use the PKCS11 verification APIs
604 * here to prevent the use of OpenSSL and to keep
605 * all validation within the FIPS-140 boundary for
606 * the Cryptographic Framework.
608 kstype
= KMF_KEYSTORE_PK11TOKEN
;
611 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_KEYSTORE_TYPE_ATTR
,
612 &kstype
, sizeof (kstype
));
613 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_DATA_ATTR
,
614 &indata
, sizeof (KMF_DATA
));
615 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_IN_SIGN_ATTR
,
616 &insig
, sizeof (KMF_DATA
));
617 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_SIGNER_CERT_DATA_ATTR
,
618 (KMF_DATA
*)(&cert
->c_cert
.certificate
), sizeof (KMF_DATA
));
619 kmf_set_attr_at_index(attrlist
, numattr
++, KMF_ALGORITHM_INDEX_ATTR
,
620 &algid
, sizeof (algid
));
622 rv
= kmf_verify_data(ess
->es_kmfhandle
, numattr
, attrlist
);
624 return ((rv
== KMF_OK
));
635 elfcertlib_getdn(ELFCert_t cert
)
637 cryptodebug("elfcertlib_getdn");
639 return (cert
->c_subject
);
643 * elfcertlib_getissuer
650 elfcertlib_getissuer(ELFCert_t cert
)
652 cryptodebug("elfcertlib_issuer");
654 return (cert
->c_issuer
);
658 elfcertlib_init(ELFsign_t ess
)
660 boolean_t rc
= B_TRUE
;
662 if (ess
->es_kmfhandle
== NULL
) {
663 rv
= kmf_initialize(&ess
->es_kmfhandle
, NULL
, NULL
);
666 "unable to initialize KMF library");
674 elfcertlib_fini(ELFsign_t ess
)
676 (void) kmf_finalize(ess
->es_kmfhandle
);
680 * set the token device
683 elfcertlib_settoken(ELFsign_t ess
, char *token
)
685 boolean_t rc
= B_TRUE
;
687 KMF_ATTRIBUTE attrlist
[8];
688 KMF_KEYSTORE_TYPE kstype
;
692 kstype
= KMF_KEYSTORE_PK11TOKEN
;
696 kmf_set_attr_at_index(attrlist
, numattr
++,
697 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
698 kmf_set_attr_at_index(attrlist
, numattr
++,
699 KMF_TOKEN_LABEL_ATTR
, token
, strlen(token
));
700 kmf_set_attr_at_index(attrlist
, numattr
++,
701 KMF_READONLY_ATTR
, &readonly
, sizeof (readonly
));
703 rv
= kmf_configure_keystore(ess
->es_kmfhandle
, numattr
, attrlist
);
705 cryptoerror(LOG_ERR
, "unable to select token\n");
713 * set the certificate CA identification callback
716 elfcertlib_setcertCAcallback(ELFsign_t ess
,
717 void (*cb
)(void *, ELFCert_t
, char *))
719 ess
->es_certCAcallback
= cb
;
723 * set the certificate verification callback
726 elfcertlib_setcertvercallback(ELFsign_t ess
,
727 void (*cb
)(void *, ELFCert_t
, ELFCert_t
))
729 ess
->es_certvercallback
= cb
;
734 * elfcertlib_releasecert - release a cert
742 elfcertlib_releasecert(ELFsign_t ess
, ELFCert_t cert
)
744 elfcertlib_freecert(ess
, cert
);
748 * elfcertlib_allocatecert - create a new ELFCert_t
752 * RETURN ELFCert_t, NULL on failure.
755 elfcertlib_allocatecert(void)
757 ELFCert_t cert
= NULL
;
759 cert
= malloc(sizeof (struct ELFCert_s
));
762 "elfcertlib_allocatecert: malloc failed %s",
766 (void) memset(cert
, 0, sizeof (struct ELFCert_s
));
767 cert
->c_verified
= E_UNCHECKED
;
768 cert
->c_subject
= NULL
;
769 cert
->c_issuer
= NULL
;
774 * elfcertlib_freecert - freeup the memory of a cert
782 elfcertlib_freecert(ELFsign_t ess
, ELFCert_t cert
)
787 free(cert
->c_subject
);
788 free(cert
->c_issuer
);
790 kmf_free_kmf_cert(ess
->es_kmfhandle
, &cert
->c_cert
);
791 kmf_free_kmf_key(ess
->es_kmfhandle
, &cert
->c_privatekey
);