pkinit_crypto_openssl.c revision 159d09a20817016f09b3ea28d1bdada4a336bb91
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * COPYRIGHT (C) 2006,2007
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * ALL RIGHTS RESERVED
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Permission is granted to use, copy, create derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * and redistribute this software and such derivative works
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * for any purpose, so long as the name of The University of
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Michigan is not used in any advertising or publicity
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * pertaining to the use of distribution of this software
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * without specific, written prior authorization. If the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * above copyright notice or any other identification of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * University of Michigan is included in any copy of any
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * portion of this software, then the disclaimer below must
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * also be included.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * SUCH DAMAGES.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Use is subject to license terms.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Q: What is this SILLYDECRYPT stuff about?
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * A: When using the ActivCard Linux pkcs11 library (v2.0.1),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * the decrypt function fails. By inserting an extra
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * function call, which serves nothing but to change the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * stack, we were able to work around the issue. If the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * ActivCard library is fixed in the future, this
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * definition and related code can be removed.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Changed to a switch statement so gettext() can be used
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * for internationization.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Use defined constants rather than raw numbers for error codes.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session parallel not supported"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("session read write so exists"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("unwrapping key handle invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("unwrapping key type inconsistent"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("user another already logged in"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("wrapping key handle invalid"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("wrapping key type inconsistent"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (gettext("cryptoki already initialized"));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* DH parameters */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: May not be thread safe! */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* initialize openssl routines */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: initializing openssl crypto context at %p\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_plg_crypto(pkinit_plg_crypto_context cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing context at %p\n", __FUNCTION__, cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_identity_crypto(pkinit_identity_crypto_context *idctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx = (pkinit_identity_crypto_context)malloc(sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_identity_crypto(pkinit_identity_crypto_context idctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, idctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_req_crypto(pkinit_req_crypto_context *cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx = (pkinit_req_crypto_context)malloc(sizeof(*ctx));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning ctx at %p\n", __FUNCTION__, ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: freeing ctx at %p\n", __FUNCTION__, req_cryptoctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If OpenSSL already knows about the OID, use the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * existing definition. Otherwise, create an OID object.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Error creating oid object for '%s'\n", oid); \
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.2.840.113549.1.7.1", id_pkinit_authData9,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* See note in pkinit_pkcs7type2oid() */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.2", id_ms_kp_sc_logon,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-ms-kp-sc-logon EKU", "Microsoft SmartCard Login EKU");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-ms-san-upn", "Microsoft Universal Principal Name");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan CREATE_OBJ_IF_NEEDED("1.3.6.1.5.5.7.3.1", id_kp_serverAuth,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "id-kp-serverAuth EKU", "Server Authentication EKU");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Success */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: May not be thread safe! */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to read certificate from %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to read private key from %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Only call OBJ_cleanup once! */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (--pkinit_oids_refs == 0) /* Solaris Kerberos: May not be thread safe! */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plgctx->dh_1024 = plgctx->dh_2048 = plgctx->dh_4096 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_certs(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < MAX_CREDS_ALLOWED; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_certs(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(ctx->intermediateCAs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_pop_free(ctx->revoked, X509_CRL_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_init_pkcs11(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Only call C_Finalize if the process was not already using pkcs11.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **signed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *digestInfo_buf = NULL, *abuf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int md_len, md_len2, alen, digestInfo_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int sig_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* start creating PKCS7 data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a cert chain that has at least the signer's certificate */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("only including signer's certificate\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a cert chain */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int i = 0, size = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_set_verify_cb_func(certstore, openssl_callback);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create a certificate chain: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("No trusted CAs found. Check your X509_anchors\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan certstack = X509_STORE_CTX_get1_chain(&certctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("size of certificate chain = %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in PKCS7_SIGNER_INFO */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* because ASN1_INTEGER_set is used to set a 'long' we will do
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * things the ugly way. */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* will not fill-out EVP_PKEY because it's on the smartcard */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Set digest algs */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_alg->parameter->type = V_ASN1_NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Set sig algs */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pick the correct oid for the eContentInfo */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* don't include signed attributes for pa-type 15 request */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* add signed attributes */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* compute sha1 digest over the EncapsulatedContentInfo */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a message digest attr */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create a content-type attr */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create the signature over signed attributes. get DER encoded value */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* This is the place where smartcard signature needs to be calculated */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Some tokens can only do RSAEncryption without sha1 hash */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * function and the hash value into an ASN.1 value of type DigestInfo
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * DigestInfo::=SEQUENCE {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * digestAlgorithm AlgorithmIdentifier,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * digest OCTET STRING }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* if this is not draft9 request, include digest signed attribute */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digest_buf = (unsigned char *)malloc(digest_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan digestInfo_len = ASN1_object_size(1, (int)(alg_len + digest_len),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan y = digestInfo_buf = (unsigned char *)malloc(digestInfo_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&y, 1, (int)(alg_len + digest_len), V_ASN1_SEQUENCE,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(digestInfo_buf, digestInfo_len, "/tmp/pkcs7_tosign");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data(context, id_cryptoctx, digestInfo_buf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Add signature */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to add a signed digest attribute\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* adder signer_info to pkcs7 signed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* start on adding data to the pkcs7 signed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pkinit_data->value.octet_string = ASN1_OCTET_STRING_new()) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!ASN1_OCTET_STRING_set(pkinit_data->value.octet_string, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!PKCS7_set0_type_other(inner_p7, OBJ_obj2nid(oid), pkinit_data))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned char *) malloc((size_t)*signed_data_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* DER encode PKCS7 data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*signed_data, *signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*signed_data, *signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*signed_data, *signed_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *signed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **authz_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = signed_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_verified_chain = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Do this early enough to create the shadow OID for pkcs7-data if needed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode received PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* verify that the received message is PKCS7 SignedData message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "wrong oid\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* setup to verify X509 certificate used to sign PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check if we are inforcing CRL checking */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_set_verify_cb_func(store, openssl_callback);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the signer's information from the PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create available CRL information (get local CRLs and include CRLs
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * received in the PKCS7 message
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_push(revoked, sk_X509_CRL_value(idctx->revoked, i));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_CRL_push(revoked, sk_X509_CRL_value(p7->d.sign->crl, i));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create available intermediate CAs chains (get local intermediateCAs and
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * include the CA chain received in the PKCS7 message
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* initialize x509 context with the received certificate and
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * trusted and intermediate CA chains and CRLs
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* add trusted CAs certificates for cert verification */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("untrusted cert chain of size %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("trusted cert chain of size %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i <= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan reqctx->received_cert = X509_dup(cert_ctx.current_cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("received cert chain of size %d\n", size);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0; j < size; j++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* retrieve verified certificate chain */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Various implementations of the pa-type 15 request use
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * different OIDS. We check that the returned object
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * has any of the acceptable OIDs
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned int)p7->d.sign->contents->type->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "wrong oid\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* transfer the data from PKCS7 message into return buffer */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (size = 0;;) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*data = realloc(*data, size + 1024 * 10)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* generate authorization data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (authz_data == NULL || authz_data_len == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_identifiers_from_stack(verified_chain,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("create_identifiers_from_stack failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_verified_chain, &authz);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)authz->data, authz->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *authz_data = (unsigned char *)malloc(authz->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(*authz_data, authz->data, authz->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idctx->intermediateCAs != NULL && p7->d.sign->cert)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_external_principal_identifier(&krb5_verified_chain);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *key_pack,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *out_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL, *signed_data = NULL, *enc_data = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int signed_data_len = 0, enc_data_len = 0, flags = PKCS7_BINARY;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* create the PKCS7 SignedData portion of the PKCS7 EnvelopedData */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan switch ((int)pa_type) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_create(context, plgctx, reqctx, idctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cms_msg_type, include_certchain, key_pack, key_pack_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &signed_data, (unsigned int *)&signed_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to create pkcs7 signed data\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check we have client's certificate */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan prepare_enc_data(signed_data, signed_data_len, &enc_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = BIO_write(in, signed_data, signed_data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!*out_len || (p = *out = (unsigned char *)malloc(*out_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(*out, *out_len, "/tmp/kdc_enveloped_data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *enveloped_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *data_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int size = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = enveloped_data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int tmp_buf_len = 0, tmp_buf2_len = 0, vfy_buf_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *tmp_buf = NULL, *tmp_buf2 = NULL, *vfy_buf = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(enveloped_data, enveloped_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode received PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p7 = d2i_PKCS7(NULL, &p, (int)enveloped_data_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* verify that the received message is PKCS7 EnvelopedData message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (OBJ_obj2nid(p7->type) != NID_pkcs7_enveloped) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Expected id-enveloped PKCS7 msg (received type = %d)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, retval, "wrong oid\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decrypt received PKCS7 message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkcs7_decrypt(context, id_cryptoctx, p7, out)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* transfer the decoded PKCS7 SignedData message into a separate buffer */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((tmp_buf = realloc(tmp_buf, size + 1024 * 10)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(tmp_buf, tmp_buf_len, "/tmp/client_enc_keypack");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* verify PKCS7 SignedData message */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: unrecognized pa_type = %d\n", __FUNCTION__, pa_type);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If this is the RFC style, wrap the signed data to make
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * decoding easier in the verify routine.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * For draft9-compatible, we don't do anything because it
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * is already wrapped.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * The Longhorn server returns the expected RFC-style data, but
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * it is missing the sequence tag and length, so it requires
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * special processing when wrapping.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This will hopefully be fixed before the final release and
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * this can all be removed.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (msg_type == CMS_ENVEL_SERVER || longhorn == 1) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin(vfy_buf, vfy_buf_len, "/tmp/client_enc_keypack2");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = cms_signeddata_verify(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char ***dns_ret)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int p = 0, u = 0, d = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: no certificate!\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int num_sans = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!(ext = X509_get_ext(cert, i)) || !(ialt = X509V3_EXT_d2i(ext))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found no subject alt name extensions\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found %d subject alt name extension(s)\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* OK, we're likely returning something. Allocate return values */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan princs = calloc(num_sans + 1, sizeof(krb5_principal));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan upns = calloc(num_sans + 1, sizeof(krb5_principal));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < num_sans; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan name.length = gen->d.otherName->value->value.sequence->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan name.data = (char *)gen->d.otherName->value->value.sequence->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)name.data, name.length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = k5int_decode_krb5_principal_name(&name, &princs[p]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed decoding pkinit san value\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = krb5_parse_name(context, name.data, &upns[u]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed parsing ms-upn san value\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: unrecognized othername oid in SAN\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dnss[d] = (unsigned char *)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char ***dns_ret)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: No certificate!\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return crypto_retrieve_X509_sans(context, plgctx, reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((i = X509_get_ext_by_NID(reqctx->received_cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan extusage = X509_get_ext_d2i(reqctx->received_cert, NID_ext_key_usage,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found eku info in the cert\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; found_eku == 0 && i < sk_ASN1_OBJECT_num(extusage); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: checking eku %d of %d, allow_secondary = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, i+1, sk_ASN1_OBJECT_num(extusage),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPKdc) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && OBJ_cmp(tmp_oid, plgctx->id_kp_serverAuth) == 0))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((OBJ_cmp(tmp_oid, plgctx->id_pkinit_KPClientAuth) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan && OBJ_cmp(tmp_oid, plgctx->id_ms_kp_sc_logon) == 0))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check that digitalSignature KeyUsage is present */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((usage = X509_get_ext_d2i(reqctx->received_cert,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: didn't find digitalSignature KU\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning retval %d, valid_eku %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char counter;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((buf = (unsigned char *) malloc(dh_key_len)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(buf + offset, md, dh_key_len - offset);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_keylengths(context, etype, &keybytes, &keylength);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan key_block->contents = calloc(keylength, sizeof(unsigned char *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = krb5_c_random_to_key(context, etype, &random_data, key_block);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (retval && key_block->contents != NULL && key_block->length != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(key_block->contents, 0, key_block->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **dh_params,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *dh_params_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **dh_pubkey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *dh_pubkey_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh->p = get_rfc2409_prime_1024(NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Warning: dh_check failed with %d\n", dh_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to check the generator value\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_dh(cryptoctx->dh, "client's DH params\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_pubkey(cryptoctx->dh->pub_key, "client's pub_key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pack DHparams */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* aglo: usually we could just call i2d_DHparams to encode DH params
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pack DH public key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * encoding shall be used as the contents (the value) of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * data element
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **client_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode subjectPublicKey (retrieve INTEGER from OCTET_STRING) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (der_decode_data(subjectPublicKey_data, (long)subjectPublicKey_length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to decode subjectPublicKey\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*client_key = (unsigned char *)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pub_key = d2i_ASN1_INTEGER(NULL, &p, data_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((server_pub_key = ASN1_INTEGER_to_BN(pub_key, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_compute_key(*client_key, server_pub_key, cryptoctx->dh);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_pubkey(server_pub_key, "server's pub_key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client secret key (%d)= ", *client_key_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* KDC SHOULD check to see if the key parameters satisfy its policy */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client sent dh params with %d bits, we require %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check dhparams is group 2 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_1024->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check dhparams is group 14 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_2048->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* check dhparams is group 16 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_4096->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* kdc's dh function */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **dh_pubkey,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *dh_pubkey_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **server_key,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get client's received DH parameters that we saved in server_check_dh */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* decode client's public key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* generate DH session key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan DH_compute_key(*server_key, dh->pub_key, dh_server);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_dh(dh_server, "client&server's DH params\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_pubkey(dh_server->pub_key, "server's pub_key=");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* KDC reply */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* pack DH public key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * encoding shall be used as the contents (the value) of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * data element
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan static int did_init = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* initialize openssl routines */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int bufsize = 0, r = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp = *buf = (unsigned char *)malloc((size_t) r);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&tmp, 1, bufsize, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*a)->p == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*a)->g == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*a)->q == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("create_krb5_trustedCertifiers failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_krb5_invalidCertificates(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("create_krb5_invalidCertificates failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_td_trusted_certifiers((const krb5_external_principal_identifier **)krb5_trusted_certifiers, &td_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("encode_krb5_td_trusted_certifiers failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)td_certifiers->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan td_certifiers->length, "/tmp/kdc_td_certifiers");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data = malloc (2 * sizeof(krb5_typed_data *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->data = (unsigned char *)td_certifiers->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_typed_data((const krb5_typed_data **)typed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)data->data, data->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_data = (krb5_data *)malloc(sizeof(krb5_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*out_data)->data = (char *)malloc(data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy((*out_data)->data, data->data, data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_external_principal_identifier(&krb5_trusted_certifiers);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_create_td_trusted_certifiers(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_create_sequence_of_principal_identifiers(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_create_sequence_of_principal_identifiers(context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_create_td_dh_parameters(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[2] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[2]->parameters.data = (unsigned char *)malloc(buf1_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[2]->parameters.data, buf1, buf1_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId = malloc(3 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[1]->parameters.data = (unsigned char *)malloc(buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[1]->parameters.data, buf3, buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId = malloc(2 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan algId[0]->parameters.data = (unsigned char *)malloc(buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(algId[0]->parameters.data, buf3, buf3_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_td_dh_parameters((const krb5_algorithm_identifier **)algId, &encoded_algId);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)encoded_algId->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan encoded_algId->length, "/tmp/kdc_td_dh_params");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data = malloc (2 * sizeof(krb5_typed_data *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan typed_data[0]->data = (unsigned char *)encoded_algId->data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = k5int_encode_krb5_typed_data((const krb5_typed_data**)typed_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan print_buffer_bin((unsigned char *)data->data, data->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *out_data = (krb5_data *)malloc(sizeof(krb5_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (*out_data)->data = (char *)malloc(data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy((*out_data)->data, data->data, data->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *pdid_buf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int pkid_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = pdid_buf;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is = d2i_PKCS7_ISSUER_AND_SERIAL(NULL, &p, (int)pkid_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("good %d dhparams\n", BN_num_bits(p1));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("p is not well-known group 2 dhparameter\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_process_td_dh_params(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (algId[i]->algorithm.length != dh_oid.length ||
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("DH parameters provided by server are unacceptable\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("callback function: %d (%s)\n", ctx->error,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanopenssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Delay creating this OID until we know we need it.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * It shadows an existing OpenSSL oid. If it
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * is created too early, it breaks things like
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * the use of pkcs12 (which uses pkcs7 structures).
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We need this shadow version because our code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * depends on the "other" type to be unknown to the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * OpenSSL code.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan nid = OBJ_create("1.2.840.113549.1.7.1", "id-pkcs7-data",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "PKCS7 data");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cryptoctx->id_pkinit_authData9 = OBJ_nid2obj(nid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This is a version that worked with Longhorn Beta 3.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanwrap_signeddata(unsigned char *data, unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get length to wrap the original data with SEQUENCE tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Add the signedData OID and adjust lengths */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This is a version that works with a patched Longhorn KDC.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * (Which should match SP1 ??).
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanwrap_signeddata(unsigned char *data, unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int oid_len = 0, tot_len = 0, wrap_len = 0, tag_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: This is the Longhorn version and is_longhorn_server = %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* New longhorn is missing another sequence */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan wrap_len = ASN1_object_size(1, (int)(data_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get length to wrap the original data with SEQUENCE tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tag_len = ASN1_object_size(1, (int)wrap_len, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Always add oid */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = ASN1_object_size(1, (int)(oid_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)wrap_len, 0, V_ASN1_CONTEXT_SPECIFIC);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Wrap in extra seq tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanwrap_signeddata(unsigned char *data, unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int orig_len = 0, oid_len = 0, tot_len = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get length to wrap the original data with SEQUENCE tag */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = orig_len = ASN1_object_size(1, (int)data_len, V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Add the signedData OID and adjust lengths */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tot_len = ASN1_object_size(1, (int)(orig_len+oid_len), V_ASN1_SEQUENCE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **outdata,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.q = *(const unsigned char **)&indata;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan c.p= *(const unsigned char **)&indata;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *outdata = (unsigned char *)malloc((size_t)Tlen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos - Changes for gettext() */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((prompt = (char *) malloc(prompt_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) snprintf(prompt, prompt_len, gettext("%.*s PIN"), sizeof (tip->label), tip->label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) strlcat(prompt, gettext(" (Warning: PIN locked)"), prompt_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) strlcat(prompt, gettext(" (Warning: PIN final try)"), prompt_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) strlcat(prompt, gettext(" (Warning: PIN count low)"), prompt_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rdat.data = (char *)malloc(tip->ulMaxPinLen + 2);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* PROMPTER_INVOCATION */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Login: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return 0; /* session already open */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Load module */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkinit_C_LoadModule(cctx->p11_module_name, &cctx->p11);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Don't fail if cryptoki is already initialized */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != CKR_OK && r != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Initialize: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If C_Initialize was already called by the process before the pkinit
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * module was loaded then record that fact.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * "finalize_pkcs11" is used by pkinit_fini_pkcs11 to determine whether
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * or not C_Finalize() should be called.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (r == CKR_CRYPTOKI_ALREADY_INITIALIZED ? FALSE : TRUE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get the list of available slots */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* A slot was specified, so that's the only one in the list */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan slotlist = (CK_SLOT_ID_PTR) malloc(sizeof (CK_SLOT_ID));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->p11->C_GetSlotList(TRUE, NULL, &count) != CKR_OK)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan slotlist = (CK_SLOT_ID_PTR) malloc(count * sizeof (CK_SLOT_ID));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Look for the given token label, or if none given take the first one */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < count; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Open session */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_OpenSession: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get token info */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo)) != CKR_OK) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetTokenInfo: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (cp = tinfo.label + sizeof (tinfo.label) - 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("open_session: slotid %d token \"%s\"\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan !strcmp((char *) cctx->token_label, (char *) tinfo.label))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("open_session: no matching token found\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("open_session: slotid %d (%d of %d)\n", (int) cctx->slotid,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Login if needed */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Look for a key that's:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 1. private
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 2. capable of the specified operation (usually signing or decrypting)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 3. RSA (this may be wrong but it's all we can do for now)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * 4. matches the id of the cert we chose
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * You must call pkinit_get_certs before calling pkinit_find_private_key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * (that's because we need the ID of the private key)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * pkcs11 says the id of the key doesn't have to match that of the cert, but
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * I can't figure out any other way to decide which key to use.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We should only find one key that fits all the requirements.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If there are more than one, we just take the first one.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int nattrs = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Some cards get confused if you try to specify a key usage,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * so don't, and hope for the best. This will fail if you have
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * several keys with the same id and different usages but I have
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * not seen this on real cards.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * The CKA_ID may not be correctly set for the private key. For e.g. when
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * storing a private key in softtoken pktool(1) doesn't generate or store
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * a CKA_ID for the private key. Another way to identify the private key is
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to look for a private key with the same RSA modulus as the public key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * in the certificate.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int n_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *n_bytes;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = sk_X509_value(id_cryptoctx->my_certs, 0);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Failed to extract pub key from cert\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan n_bytes = (unsigned char *) malloc((size_t) n_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **decoded_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (decode_data(decoded_data, decoded_data_len, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->my_key, sk_X509_value(id_cryptoctx->my_certs,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_C_Decrypt(pkinit_identity_crypto_context id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan rv = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, pEncryptedData,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("pData %x *pulDataLen %d\n", (int) pData, (int) *pulDataLen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **decoded_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_open_session(context, id_cryptoctx)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = pkinit_find_private_key(id_cryptoctx, CKA_DECRYPT, &obj);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_DecryptInit(id_cryptoctx->session, &mech,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cp = (unsigned char *)malloc((size_t) data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("session %x edata %x edata_len %d data %x datalen @%x %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int) id_cryptoctx->session, (int) data, (int) data_len, (int) cp,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = pkinit_C_Decrypt(id_cryptoctx, data, (CK_ULONG) data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_Decrypt(id_cryptoctx->session, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Decrypt: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decrypt %d needs %d\n", (int) data_len, (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("decrypt %d -> %d\n", (int) data_len, (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **decoded_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_decode_data_fs(context, id_cryptoctx, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_decode_data_pkcs11(context, id_cryptoctx, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *sig_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (create_signature(sig, sig_len, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *sig_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_open_session(context, id_cryptoctx)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = pkinit_find_private_key(id_cryptoctx, CKA_SIGN, &obj);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r != 0 )
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_SignInit(id_cryptoctx->session, &mech,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_SignInit: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Key len would give an upper bound on sig size, but there's no way to
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * get that. So guess, and if it's too small, re-malloc.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r == CKR_BUFFER_TOO_SMALL || (r == CKR_OK && len >= PK_SIGLEN_GUESS)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_Sign(id_cryptoctx->session, data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_Sign: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("sign %d -> %d\n", (int) data_len, (int) len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **sig,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *sig_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx == NULL || id_cryptoctx->pkcs11_method != 1)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data_fs(context, id_cryptoctx, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_sign_data_pkcs11(context, id_cryptoctx, data, data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalandecode_data(unsigned char **out_data, unsigned int *out_data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (cert && !X509_check_private_key(cert, pkey)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("private key does not match certificate\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan buf = (unsigned char *)malloc((size_t) buf_len + 10);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_signature(unsigned char **sig, unsigned int *sig_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This is not the routine the KDC uses to get its certificate.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This routine is intended to be called by the client
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to obtain the KDC's certificate from some local storage
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to be sent as a hint in its request to the KDC.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's private key location\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Failed to open PKCS12 file '%s', error %d\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to decode PKCS12 file '%s' contents"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Failed to decode PKCS12 file '%s' contents\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Try parsing with no pass phrase first. If that fails,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * prompt for the pass phrase and try again.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *prompt_prefix = gettext("Pass phrase for");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Initial PKCS12_parse with no password failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memset(prompt_reply, '\0', sizeof(prompt_reply));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = snprintf(prompt_string, sizeof(prompt_string), "%s %s",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (r >= sizeof(prompt_string)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Prompt string, '%s %s', is too long!\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* PROMPTER_INVOCATION */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to parse PKCS12 file '%s' with password"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("Seconde PKCS12_parse with password failed\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0] = malloc(sizeof(struct _pkinit_cred_info));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanpkinit_load_fs_cert_and_key(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* load the certificate */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to load user's certificate from %s: %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to load user's certificate from '%s'\n", certname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to load user's private key from %s: %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("failed to load user's private key from '%s'\n", keyname);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[cindex] = malloc(sizeof(struct _pkinit_cred_info));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's cert location\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's private key location\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: failed to get user's certificate directory location\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We'll assume that certs are named XXX.crt and the corresponding
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * key is named XXX.key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan while ((i < MAX_CREDS_ALLOWED) && (dentry = readdir(d)) != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Ignore subdirectories and anything starting with a dot */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Checked length */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(certname)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) snprintf(certname, sizeof(certname), "%s/%s", dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) snprintf(keyname, sizeof(keyname), "%s/%s", dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Successfully loaded cert (and key) for %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i == 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("No suitable cert/key pairs found in directory '%s'"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: No cert/key pairs found in directory '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *cp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int nattrs;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Copy stuff from idopts -> id_cryptoctx */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11_module_name = strdup(idopts->p11_module_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->token_label = strdup(idopts->token_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_label = strdup(idopts->cert_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Convert the ascii cert_id string into a binary blob */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If the cert_id_string is empty then behave in a similar way to how
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * an empty certlabel is treated - i.e. don't fail now but rather continue
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * as though the certid wasn't specified.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (idopts->cert_id_string != NULL && strlen(idopts->cert_id_string) != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id = malloc((size_t) id_cryptoctx->cert_id_len);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (pkinit_open_session(context, id_cryptoctx)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * many cards seems to be confused about whether they are capable of
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * this or not. The safe thing seems to be to ignore the mechanism list,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid, NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetMechanismList: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan mechp = (CK_MECHANISM_TYPE_PTR) malloc(count * sizeof (CK_MECHANISM_TYPE));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetMechanismList(id_cryptoctx->slotid,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < count; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetMechanismInfo(id_cryptoctx->slotid,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("mech %x flags %x\n", (int) mechp[i], (int) info.flags);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((info.flags & (CKF_SIGN|CKF_DECRYPT)) == (CKF_SIGN|CKF_DECRYPT))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug(" this mech is good for sign & decrypt\n");
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* This seems backwards... */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("got %d mechs from card\n", (int) count);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If a cert id and/or label were given, use them too */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].pValue = id_cryptoctx->cert_label;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan attrs[nattrs].ulValueLen = strlen(id_cryptoctx->cert_label);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_FindObjectsInit: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; ; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Look for x.509 cert */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Get cert and id len */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetAttributeValue(id_cryptoctx->session,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan obj, attrs, 2)) != CKR_OK && r != CKR_BUFFER_TOO_SMALL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert = (CK_BYTE_PTR) malloc((size_t) attrs[0].ulValueLen + 1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cert_id = (CK_BYTE_PTR) malloc((size_t) attrs[1].ulValueLen + 1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Read the cert and id off the card */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((r = id_cryptoctx->p11->C_GetAttributeValue(id_cryptoctx->session,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("C_GetAttributeValue: %s\n", pkinit_pkcs11_code_to_text(r));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan x = d2i_X509(NULL, &cp, (int) attrs[0].ulValueLen);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i] = malloc(sizeof(struct _pkinit_cred_info));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[i]->cert_id_len = attrs[1].ulValueLen;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("pkcs11 error while searching for certificates: %s"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *printstr = id_cryptoctx->cert_id_len ? cidstr : "<none>";
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to find any suitable certificates "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "(certlabel: %s, certid: %s)"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_label ? id_cryptoctx->cert_label : "<none>",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < MAX_CREDS_ALLOWED; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_cred_info(context, id_cryptoctx, id_cryptoctx->creds[i]);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_fs(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_dir(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_pkcs11(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_get_certs_pkcs12(context, plg_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get number of certificates available after crypto_load_certs()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx == NULL || id_cryptoctx->creds[0] == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan count <= MAX_CREDS_ALLOWED && id_cryptoctx->creds[count] != NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Begin iteration over the certs loaded in crypto_load_certs()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_iteration_begin(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (id_cryptoctx->creds[0] == NULL) /* No cred info available */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * End iteration over the certs loaded in crypto_load_certs()
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get next certificate handle
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_iter_data *id = (struct _pkinit_cert_iter_data *)ih;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Release cert handle
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get certificate Key Usage and Extended Key Usage
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_retieve_X509_key_usage(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *ret_ku_bits,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *ret_eku_bits)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ret_ku_bits == NULL && ret_eku_bits == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: EKUs not requested, not checking\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Start with Extended Key usage */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan i = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i >= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan eku = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((OBJ_cmp(certoid, plgcctx->id_pkinit_KPClientAuth)) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_ms_smartcard_login))) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_client_auth))) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else if ((OBJ_cmp(certoid, OBJ_nid2obj(NID_email_protect))) == 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning eku 0x%08x\n", __FUNCTION__, eku_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Now the Key Usage bits */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: KUs not requested, not checking\n", __FUNCTION__);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Make sure usage exists before checking bits */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: returning ku 0x%08x\n", __FUNCTION__, ku_bits);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Return a string format of an X509_NAME in buf where
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * size is an in/out parameter. On input it is the size
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * of the buffer, and on output it is the actual length
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * of the name.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * If buf is NULL, returns the length req'd to hold name
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *size,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned long flag)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (buf != NULL && *size > (int) BIO_number_written(out)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_read(out, buf, (int) BIO_number_written(out));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Get certificate information
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_get_matching_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal *pkinit_sans =NULL, *upn_sans = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct _pkinit_cert_data *cd = (struct _pkinit_cert_data *)ch;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the subject name (in rfc2253 format) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline_ex(X509_get_subject_name(cd->cred->cert),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the issuer name (in rfc2253 format) */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline_ex(X509_get_issuer_name(cd->cred->cert),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the san data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_retrieve_X509_sans(context, cd->plgctx, cd->reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (j != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan md->sans = calloc((size_t)j+1, sizeof(*md->sans));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* get the KU and EKU data */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_retieve_X509_key_usage(context, cd->plgctx, cd->reqctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Free certificate information
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancrypto_cert_free_matching_data(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i])
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Make this matching certificate "the chosen one"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* copy the selected cert into our id_cryptoctx */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(cd->idctx->my_certs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(cd->idctx->my_certs, cd->cred->cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->creds[cd->index]->cert = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->creds[cd->index]->key = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan cd->idctx->creds[cd->index]->cert_id = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Choose the default certificate as "the chosen one"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = crypto_cert_get_count(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: crypto_cert_get_count error %d, %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Improved error messages */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan gettext("failed to select default certificate: "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "found %d certs to choose from but there must be exactly one"),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: ERROR: There are %d certs to choose from, "
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "but there must be exactly one.\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* copy the selected cert into our id_cryptoctx */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan sk_X509_push(id_cryptoctx->my_certs, id_cryptoctx->creds[0]->cert);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->cert = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->creds[0]->cert_id = NULL; /* Don't free it twice */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan id_cryptoctx->cert_id_len = id_cryptoctx->creds[0]->cert_id_len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If there isn't already a stack in the context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * create a temporary one now */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: error opening file '%s': %s\n", __FUNCTION__,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* This loads from a file, a stack of x509/crl/pkey sets */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: error reading file '%s'\n", __FUNCTION__, filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* scan over the stack created from loading the file contents,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * weed out duplicates, and push new ones onto the return stack
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int j = 0, size = sk_X509_num(ca_certs), flag = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0; j < size; j++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else if (xi != NULL && xi->crl != NULL && catype == CATYPE_CRLS) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int j = 0, size = sk_X509_CRL_num(ca_crls), flag = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (j = 0; j < size; j++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If we added something and there wasn't a stack in the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * context before, add the temporary stack to the context.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("no intermediates in file, %s\n", filename);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Should have been caught above! */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: removed "break" as it's never reached */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (strlen(dirname) + strlen(dentry->d_name) + 2 > sizeof(filename)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: Path too long -- directory '%s' and file '%s'\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Ignore subdirectories and anything starting with a dot */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) snprintf(filename, sizeof(filename), "%s/%s", dirname, dentry->d_name);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("%s: called with idtype %s and catype %s\n",
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan __FUNCTION__, idtype2string(idtype), catype2string(catype));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: Removed "break"'s as they are never reached */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_identifiers_from_stack(STACK_OF(X509) *sk,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_cas = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan malloc((sk_size + 1) * sizeof(krb5_external_principal_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < sk_size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i] = (krb5_external_principal_identifier *)malloc(sizeof(krb5_external_principal_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in subjectName */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in issuerAndSerialNumber */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanif (longhorn == 0) { /* XXX Longhorn doesn't like this */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->issuerAndSerialNumber.length = len;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* fill-in subjectKeyIdentifier */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanif (longhorn == 0) { /* XXX Longhorn doesn't like this */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((ikeyid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = krb5_cas[i]->subjectKeyIdentifier.data =
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan free_krb5_external_principal_identifier(&krb5_cas);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_krb5_invalidCertificates(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = create_identifiers_from_stack(sk, ids);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_krb5_supportedCMSTypes(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_octet_data des3oid = {0, 8, (unsigned char *)"\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan loids[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan retval = pkinit_copy_krb5_octet_data(&loids[0]->algorithm, &des3oid);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancreate_krb5_trustedCertifiers(krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas = malloc((sk_size + 1) * sizeof(krb5_trusted_ca *));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; i < sk_size; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i] = (krb5_trusted_ca *)malloc(sizeof(krb5_trusted_ca));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->choice = choice_trusted_cas_principalName;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->choice = choice_trusted_cas_caName;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan default: break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* ARGSUSED */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char **out,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned int *out_len)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if(!(tmpmem = pkcs7_dataDecode(context, id_cryptoctx, p7))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: Suppress sun studio compiler warning */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#pragma error_messages (off, E_END_OF_LOOP_CODE_NOT_REACHED)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (i <= 0) break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#pragma error_messages (default, E_END_OF_LOOP_CODE_NOT_REACHED)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_external_principal_identifier **krb5_trusted_certifiers,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers[i]->subjectName.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = krb5_trusted_certifiers[i]->subjectName.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)krb5_trusted_certifiers[i]->subjectName.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d cert = %s is trusted by kdc\n", i, buf);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers[i]->issuerAndSerialNumber.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = krb5_trusted_certifiers[i]->issuerAndSerialNumber.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)krb5_trusted_certifiers[i]->issuerAndSerialNumber.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509_NAME_oneline(is->issuer, buf, sizeof(buf));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d issuer = %s serial = %ld is trusted bu kdc\n", i,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan pkiDebug("#%d issuer = %s serial = %ld is invalid\n", i, buf,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_trusted_certifiers[i]->subjectKeyIdentifier.data != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan p = krb5_trusted_certifiers[i]->subjectKeyIdentifier.data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (int)krb5_trusted_certifiers[i]->subjectKeyIdentifier.length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* XXX Since we not doing anything with received trusted certifiers
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * return an error. this is the place where we can pick a different
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * client certificate based on the information in td_trusted_certifiers
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: Not used */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan X509 *cert = sk_X509_value(id_cryptoctx->my_certs,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos: Not used */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* It was encrypted, we need to decrypt the secret key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * with the private key */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Find the recipientInfo which matches the passed certificate
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* If we haven't got a certificate try each ri in turn */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned int) M_ASN1_STRING_length(ri->enc_key),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (unsigned int) M_ASN1_STRING_length(ri->enc_key),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Some S/MIME clients don't use the same key
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * and effective key length. The key length is
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * determined by the size of the decrypted RSA key.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan bio = BIO_new_mem_buf(data_body->data, data_body->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalander_decode_data(unsigned char *data, long data_len,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan const unsigned char *p = data;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((s = d2i_ASN1_BIT_STRING(NULL, &p, data_len)) == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((*out = (unsigned char *) malloc((size_t) *out_len + 1)) == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (void) memcpy(*out, s->data, (size_t) s->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Solaris Kerberos:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Error message generation has changed so gettext() can be used
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i = 0; pkcs11_errstrings[i].text != NULL; i++)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan snprintf(uc, 64, gettext("unknown code 0x%x"), err);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic char *