2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2N/A * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * COPYRIGHT (C) 2006,2007 2N/A * THE REGENTS OF THE UNIVERSITY OF MICHIGAN 2N/A * ALL RIGHTS RESERVED 2N/A * Permission is granted to use, copy, create derivative works 2N/A * and redistribute this software and such derivative works 2N/A * for any purpose, so long as the name of The University of 2N/A * Michigan is not used in any advertising or publicity 2N/A * pertaining to the use of distribution of this software 2N/A * without specific, written prior authorization. If the 2N/A * above copyright notice or any other identification of the 2N/A * University of Michigan is included in any copy of any 2N/A * portion of this software, then the disclaimer below must 2N/A * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION 2N/A * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY 2N/A * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF 2N/A * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING 2N/A * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF 2N/A * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 2N/A * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE 2N/A * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR 2N/A * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING 2N/A * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN 2N/A * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF 2N/A * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A/* Solaris Kerberos */ 2N/A * Q: What is this SILLYDECRYPT stuff about? 2N/A * A: When using the ActivCard Linux pkcs11 library (v2.0.1), 2N/A * the decrypt function fails. By inserting an extra 2N/A * function call, which serves nothing but to change the 2N/A * stack, we were able to work around the issue. If the 2N/A * ActivCard library is fixed in the future, this 2N/A * definition and related code can be removed. 2N/A/* Use CMS support present in OpenSSL 1.0 and later. */ 2N/A/* Fake up CMS support using PKCS7. */ 2N/A * Changed to a switch statement so gettext() can be used 2N/A * for internationization. 2N/A * Use defined constants rather than raw numbers for error codes. 2N/A return (
gettext(
"session parallel not supported"));
2N/A return (
gettext(
"unwrapping key handle invalid"));
2N/A return (
gettext(
"unwrapping key type inconsistent"));
2N/A return (
gettext(
"user another already logged in"));
2N/A return (
gettext(
"wrapping key type inconsistent"));
2N/A 0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
2N/A 0xC9,
0x0F,
0xDA,
0xA2,
0x21,
0x68,
0xC2,
0x34,
2N/A 0xC4,
0xC6,
0x62,
0x8B,
0x80,
0xDC,
0x1C,
0xD1,
2N/A 0x29,
0x02,
0x4E,
0x08,
0x8A,
0x67,
0xCC,
0x74,
2N/A 0x02,
0x0B,
0xBE,
0xA6,
0x3B,
0x13,
0x9B,
0x22,
2N/A 0x51,
0x4A,
0x08,
0x79,
0x8E,
0x34,
0x04,
0xDD,
2N/A 0xEF,
0x95,
0x19,
0xB3,
0xCD,
0x3A,
0x43,
0x1B,
2N/A 0x30,
0x2B,
0x0A,
0x6D,
0xF2,
0x5F,
0x14,
0x37,
2N/A 0x4F,
0xE1,
0x35,
0x6D,
0x6D,
0x51,
0xC2,
0x45,
2N/A 0xE4,
0x85,
0xB5,
0x76,
0x62,
0x5E,
0x7E,
0xC6,
2N/A 0xF4,
0x4C,
0x42,
0xE9,
0xA6,
0x37,
0xED,
0x6B,
2N/A 0x0B,
0xFF,
0x5C,
0xB6,
0xF4,
0x06,
0xB7,
0xED,
2N/A 0xEE,
0x38,
0x6B,
0xFB,
0x5A,
0x89,
0x9F,
0xA5,
2N/A 0xAE,
0x9F,
0x24,
0x11,
0x7C,
0x4B,
0x1F,
0xE6,
2N/A 0x49,
0x28,
0x66,
0x51,
0xEC,
0xE6,
0x53,
0x81,
2N/A 0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF 2N/A 0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
2N/A 0xC9,
0x0F,
0xDA,
0xA2,
0x21,
0x68,
0xC2,
0x34,
2N/A 0xC4,
0xC6,
0x62,
0x8B,
0x80,
0xDC,
0x1C,
0xD1,
2N/A 0x29,
0x02,
0x4E,
0x08,
0x8A,
0x67,
0xCC,
0x74,
2N/A 0x02,
0x0B,
0xBE,
0xA6,
0x3B,
0x13,
0x9B,
0x22,
2N/A 0x51,
0x4A,
0x08,
0x79,
0x8E,
0x34,
0x04,
0xDD,
2N/A 0xEF,
0x95,
0x19,
0xB3,
0xCD,
0x3A,
0x43,
0x1B,
2N/A 0x30,
0x2B,
0x0A,
0x6D,
0xF2,
0x5F,
0x14,
0x37,
2N/A 0x4F,
0xE1,
0x35,
0x6D,
0x6D,
0x51,
0xC2,
0x45,
2N/A 0xE4,
0x85,
0xB5,
0x76,
0x62,
0x5E,
0x7E,
0xC6,
2N/A 0xF4,
0x4C,
0x42,
0xE9,
0xA6,
0x37,
0xED,
0x6B,
2N/A 0x0B,
0xFF,
0x5C,
0xB6,
0xF4,
0x06,
0xB7,
0xED,
2N/A 0xEE,
0x38,
0x6B,
0xFB,
0x5A,
0x89,
0x9F,
0xA5,
2N/A 0xAE,
0x9F,
0x24,
0x11,
0x7C,
0x4B,
0x1F,
0xE6,
2N/A 0x49,
0x28,
0x66,
0x51,
0xEC,
0xE4,
0x5B,
0x3D,
2N/A 0xC2,
0x00,
0x7C,
0xB8,
0xA1,
0x63,
0xBF,
0x05,
2N/A 0x98,
0xDA,
0x48,
0x36,
0x1C,
0x55,
0xD3,
0x9A,
2N/A 0x69,
0x16,
0x3F,
0xA8,
0xFD,
0x24,
0xCF,
0x5F,
2N/A 0x83,
0x65,
0x5D,
0x23,
0xDC,
0xA3,
0xAD,
0x96,
2N/A 0x1C,
0x62,
0xF3,
0x56,
0x20,
0x85,
0x52,
0xBB,
2N/A 0x9E,
0xD5,
0x29,
0x07,
0x70,
0x96,
0x96,
0x6D,
2N/A 0x67,
0x0C,
0x35,
0x4E,
0x4A,
0xBC,
0x98,
0x04,
2N/A 0xF1,
0x74,
0x6C,
0x08,
0xCA,
0x18,
0x21,
0x7C,
2N/A 0x32,
0x90,
0x5E,
0x46,
0x2E,
0x36,
0xCE,
0x3B,
2N/A 0xE3,
0x9E,
0x77,
0x2C,
0x18,
0x0E,
0x86,
0x03,
2N/A 0x9B,
0x27,
0x83,
0xA2,
0xEC,
0x07,
0xA2,
0x8F,
2N/A 0xB5,
0xC5,
0x5D,
0xF0,
0x6F,
0x4C,
0x52,
0xC9,
2N/A 0xDE,
0x2B,
0xCB,
0xF6,
0x95,
0x58,
0x17,
0x18,
2N/A 0x39,
0x95,
0x49,
0x7C,
0xEA,
0x95,
0x6A,
0xE5,
2N/A 0x15,
0xD2,
0x26,
0x18,
0x98,
0xFA,
0x05,
0x10,
2N/A 0x15,
0x72,
0x8E,
0x5A,
0x8A,
0xAC,
0xAA,
0x68,
2N/A 0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF 2N/A 0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
2N/A 0xC9,
0x0F,
0xDA,
0xA2,
0x21,
0x68,
0xC2,
0x34,
2N/A 0xC4,
0xC6,
0x62,
0x8B,
0x80,
0xDC,
0x1C,
0xD1,
2N/A 0x29,
0x02,
0x4E,
0x08,
0x8A,
0x67,
0xCC,
0x74,
2N/A 0x02,
0x0B,
0xBE,
0xA6,
0x3B,
0x13,
0x9B,
0x22,
2N/A 0x51,
0x4A,
0x08,
0x79,
0x8E,
0x34,
0x04,
0xDD,
2N/A 0xEF,
0x95,
0x19,
0xB3,
0xCD,
0x3A,
0x43,
0x1B,
2N/A 0x30,
0x2B,
0x0A,
0x6D,
0xF2,
0x5F,
0x14,
0x37,
2N/A 0x4F,
0xE1,
0x35,
0x6D,
0x6D,
0x51,
0xC2,
0x45,
2N/A 0xE4,
0x85,
0xB5,
0x76,
0x62,
0x5E,
0x7E,
0xC6,
2N/A 0xF4,
0x4C,
0x42,
0xE9,
0xA6,
0x37,
0xED,
0x6B,
2N/A 0x0B,
0xFF,
0x5C,
0xB6,
0xF4,
0x06,
0xB7,
0xED,
2N/A 0xEE,
0x38,
0x6B,
0xFB,
0x5A,
0x89,
0x9F,
0xA5,
2N/A 0xAE,
0x9F,
0x24,
0x11,
0x7C,
0x4B,
0x1F,
0xE6,
2N/A 0x49,
0x28,
0x66,
0x51,
0xEC,
0xE4,
0x5B,
0x3D,
2N/A 0xC2,
0x00,
0x7C,
0xB8,
0xA1,
0x63,
0xBF,
0x05,
2N/A 0x98,
0xDA,
0x48,
0x36,
0x1C,
0x55,
0xD3,
0x9A,
2N/A 0x69,
0x16,
0x3F,
0xA8,
0xFD,
0x24,
0xCF,
0x5F,
2N/A 0x83,
0x65,
0x5D,
0x23,
0xDC,
0xA3,
0xAD,
0x96,
2N/A 0x1C,
0x62,
0xF3,
0x56,
0x20,
0x85,
0x52,
0xBB,
2N/A 0x9E,
0xD5,
0x29,
0x07,
0x70,
0x96,
0x96,
0x6D,
2N/A 0x67,
0x0C,
0x35,
0x4E,
0x4A,
0xBC,
0x98,
0x04,
2N/A 0xF1,
0x74,
0x6C,
0x08,
0xCA,
0x18,
0x21,
0x7C,
2N/A 0x32,
0x90,
0x5E,
0x46,
0x2E,
0x36,
0xCE,
0x3B,
2N/A 0xE3,
0x9E,
0x77,
0x2C,
0x18,
0x0E,
0x86,
0x03,
2N/A 0x9B,
0x27,
0x83,
0xA2,
0xEC,
0x07,
0xA2,
0x8F,
2N/A 0xB5,
0xC5,
0x5D,
0xF0,
0x6F,
0x4C,
0x52,
0xC9,
2N/A 0xDE,
0x2B,
0xCB,
0xF6,
0x95,
0x58,
0x17,
0x18,
2N/A 0x39,
0x95,
0x49,
0x7C,
0xEA,
0x95,
0x6A,
0xE5,
2N/A 0x15,
0xD2,
0x26,
0x18,
0x98,
0xFA,
0x05,
0x10,
2N/A 0x15,
0x72,
0x8E,
0x5A,
0x8A,
0xAA,
0xC4,
0x2D,
2N/A 0xAD,
0x33,
0x17,
0x0D,
0x04,
0x50,
0x7A,
0x33,
2N/A 0xA8,
0x55,
0x21,
0xAB,
0xDF,
0x1C,
0xBA,
0x64,
2N/A 0xEC,
0xFB,
0x85,
0x04,
0x58,
0xDB,
0xEF,
0x0A,
2N/A 0x8A,
0xEA,
0x71,
0x57,
0x5D,
0x06,
0x0C,
0x7D,
2N/A 0xB3,
0x97,
0x0F,
0x85,
0xA6,
0xE1,
0xE4,
0xC7,
2N/A 0xAB,
0xF5,
0xAE,
0x8C,
0xDB,
0x09,
0x33,
0xD7,
2N/A 0x1E,
0x8C,
0x94,
0xE0,
0x4A,
0x25,
0x61,
0x9D,
2N/A 0xCE,
0xE3,
0xD2,
0x26,
0x1A,
0xD2,
0xEE,
0x6B,
2N/A 0xF1,
0x2F,
0xFA,
0x06,
0xD9,
0x8A,
0x08,
0x64,
2N/A 0xD8,
0x76,
0x02,
0x73,
0x3E,
0xC8,
0x6A,
0x64,
2N/A 0x52,
0x1F,
0x2B,
0x18,
0x17,
0x7B,
0x20,
0x0C,
2N/A 0xBB,
0xE1,
0x17,
0x57,
0x7A,
0x61,
0x5D,
0x6C,
2N/A 0x77,
0x09,
0x88,
0xC0,
0xBA,
0xD9,
0x46,
0xE2,
2N/A 0x08,
0xE2,
0x4F,
0xA0,
0x74,
0xE5,
0xAB,
0x31,
2N/A 0x43,
0xDB,
0x5B,
0xFC,
0xE0,
0xFD,
0x10,
0x8E,
2N/A 0x4B,
0x82,
0xD1,
0x20,
0xA9,
0x21,
0x08,
0x01,
2N/A 0x1A,
0x72,
0x3C,
0x12,
0xA7,
0x87,
0xE6,
0xD7,
2N/A 0x88,
0x71,
0x9A,
0x10,
0xBD,
0xBA,
0x5B,
0x26,
2N/A 0x99,
0xC3,
0x27,
0x18,
0x6A,
0xF4,
0xE2,
0x3C,
2N/A 0x1A,
0x94,
0x68,
0x34,
0xB6,
0x15,
0x0B,
0xDA,
2N/A 0x25,
0x83,
0xE9,
0xCA,
0x2A,
0xD4,
0x4C,
0xE8,
2N/A 0xDB,
0xBB,
0xC2,
0xDB,
0x04,
0xDE,
0x8E,
0xF9,
2N/A 0x2E,
0x8E,
0xFC,
0x14,
0x1F,
0xBE,
0xCA,
0xA6,
2N/A 0x28,
0x7C,
0x59,
0x47,
0x4E,
0x6B,
0xC0,
0x5D,
2N/A 0x99,
0xB2,
0x96,
0x4F,
0xA0,
0x90,
0xC3,
0xA2,
2N/A 0x23,
0x3B,
0xA1,
0x86,
0x51,
0x5B,
0xE7,
0xED,
2N/A 0x1F,
0x61,
0x29,
0x70,
0xCE,
0xE2,
0xD7,
0xAF,
2N/A 0xB8,
0x1B,
0xDD,
0x76,
0x21,
0x70,
0x48,
0x1C,
2N/A 0xD0,
0x06,
0x91,
0x27,
0xD5,
0xB0,
0x5A,
0xA9,
2N/A 0x93,
0xB4,
0xEA,
0x98,
0x8D,
0x8F,
0xDD,
0xC1,
2N/A 0x86,
0xFF,
0xB7,
0xDC,
0x90,
0xA6,
0xC0,
0x8F,
2N/A 0x4D,
0xF4,
0x35,
0xC9,
0x34,
0x06,
0x31,
0x99,
2N/A 0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF 2N/A/* Solaris Kerberos */ 2N/A /* initialize openssl routines */ 2N/A /* Solaris Kerberos */ 2N/A pkiDebug(
"%s: initializing openssl crypto context at %p\n",
2N/A /* Solaris Kerberos */ 2N/A * If OpenSSL already knows about the OID, use the 2N/A * existing definition. Otherwise, create an OID object. 2N/A /* Solaris Kerberos */ 2N/A "id-pkinit-san",
"KRB5PrincipalName");
2N/A "id-pkinit-authdata",
"PKINIT signedAuthPack");
2N/A "id-pkinit-DHKeyData",
"PKINIT dhSignedData");
2N/A "id-pkinit-rkeyData",
"PKINIT encKeyPack");
2N/A "id-pkinit-KPClientAuth",
"PKINIT Client EKU");
2N/A "id-pkinit-KPKdc",
"KDC EKU");
2N/A "id-pkcs7-data",
"PKCS7 data");
2N/A /* See note in pkinit_pkcs7type2oid() */ 2N/A "id-ms-kp-sc-logon EKU",
"Microsoft SmartCard Login EKU");
2N/A "id-ms-san-upn",
"Microsoft Universal Principal Name");
2N/A "id-kp-serverAuth EKU",
"Server Authentication EKU");
2N/A /* Solaris Kerberos */ 2N/A /* Only call OBJ_cleanup once! */ 2N/A /* Solaris Kerberos: locking */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A * Only call C_Finalize if the process was not already using pkcs11. 2N/A/*helper function for creating pkinit ContentInfo*/ 2N/A /* Pick the correct oid for the eContentInfo. */ 2N/A /* DER encode PKCS7 data */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* start creating PKCS7 data */ 2N/A /* create a cert chain that has at least the signer's certificate */ 2N/A /* create a cert chain */ 2N/A /* Solaris Kerberos */ 2N/A pkiDebug(
"No trusted CAs found. Check your X509_anchors\n");
2N/A /* fill-in PKCS7_SIGNER_INFO */ 2N/A /* because ASN1_INTEGER_set is used to set a 'long' we will do 2N/A * things the ugly way. */ 2N/A /* will not fill-out EVP_PKEY because it's on the smartcard */ 2N/A /* Set digest algs */ 2N/A /* pick the correct oid for the eContentInfo */ 2N/A /* don't include signed attributes for pa-type 15 request */ 2N/A /* add signed attributes */ 2N/A /* compute sha1 digest over the EncapsulatedContentInfo */ 2N/A /* create a message digest attr */ 2N/A /* create a content-type attr */ 2N/A /* create the signature over signed attributes. get DER encoded value */ 2N/A /* This is the place where smartcard signature needs to be calculated */ 2N/A /* Some tokens can only do RSAEncryption without sha1 hash */ 2N/A /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash 2N/A * function and the hash value into an ASN.1 value of type DigestInfo 2N/A * DigestInfo::=SEQUENCE { 2N/A * digestAlgorithm AlgorithmIdentifier, 2N/A * digest OCTET STRING } 2N/A /* if this is not draft9 request, include digest signed attribute */ 2N/A /* adder signer_info to pkcs7 signed */ 2N/A /* start on adding data to the pkcs7 signed */ 2N/A /* DER encode PKCS7 data */ 2N/A /* Solaris Kerberos */ 2N/A /* Do this early enough to create the shadow OID for pkcs7-data if needed */ 2N/A /* decode received CMS message */ 2N/A /* Handle the case in pkinit anonymous where we get unsigned data. */ 2N/A "Invalid pkinit packet: octet string " 2N/A /* Verify that the received message is CMS SignedData message. */ 2N/A pkiDebug(
"Expected id-signedData CMS msg (received type = %d)\n",
2N/A /* setup to verify X509 certificate used to sign CMS message */ 2N/A /* check if we are inforcing CRL checking */ 2N/A /* get the signer's information from the CMS message */ 2N/A /* create available CRL information (get local CRLs and include CRLs 2N/A * received in the CMS message 2N/A /* create available intermediate CAs chains (get local intermediateCAs and 2N/A * include the CA chain received in the CMS message 2N/A /* initialize x509 context with the received certificate and 2N/A * trusted and intermediate CA chains and CRLs 2N/A /* add trusted CAs certificates for cert verification */ 2N/A /* Solaris Kerberos */ 2N/A /* retrieve verified certificate chain */ 2N/A /* Solaris Kerberos */ 2N/A * Various implementations of the pa-type 15 request use 2N/A * different OIDS. We check that the returned object 2N/A * has any of the acceptable OIDs 2N/A /* transfer the data from CMS message into return buffer */ 2N/A /* generate authorization data */ 2N/A pkiDebug(
"encode_krb5_td_trusted_certifiers failed\n");
2N/A /* Solaris Kerberos */ 2N/A /* create the PKCS7 SignedData portion of the PKCS7 EnvelopedData */ 2N/A /* Solaris Kerberos */ 2N/A /* check we have client's certificate */ 2N/A /* Solaris Kerberos */ 2N/A /* decode received PKCS7 message */ 2N/A /* verify that the received message is PKCS7 EnvelopedData message */ 2N/A pkiDebug(
"Expected id-enveloped PKCS7 msg (received type = %d)\n",
2N/A /* decrypt received PKCS7 message */ 2N/A /* transfer the decoded PKCS7 SignedData message into a separate buffer */ 2N/A /* verify PKCS7 SignedData message */ 2N/A * If this is the RFC style, wrap the signed data to make 2N/A * decoding easier in the verify routine. 2N/A * For draft9-compatible, we don't do anything because it 2N/A * is already wrapped. 2N/A * The Longhorn server returns the expected RFC-style data, but 2N/A * it is missing the sequence tag and length, so it requires 2N/A * special processing when wrapping. 2N/A * This will hopefully be fixed before the final release and 2N/A * this can all be removed. 2N/A int p = 0, u = 0, d = 0;
2N/A pkiDebug(
"%s: found %d subject alt name extension(s)\n",
2N/A /* OK, we're likely returning something. Allocate return values */ 2N/A /* Solaris Kerberos */ 2N/A pkiDebug(
"%s: checking eku %d of %d, allow_secondary = %d\n",
2N/A /* check that digitalSignature KeyUsage is present */ 2N/A /* Solaris Kerberos */ 2N/A/* Solaris Kerberos */ 2N/A /* aglo: usually we could just call i2d_DHparams to encode DH params 2N/A * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3. 2N/A /* pack DH public key */ 2N/A /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this 2N/A * encoding shall be used as the contents (the value) of the 2N/A * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo 2N/A /* Solaris Kerberos */ 2N/A /* decode subjectPublicKey (retrieve INTEGER from OCTET_STRING) */ 2N/A /* Solaris Kerberos */ 2N/A /* KDC SHOULD check to see if the key parameters satisfy its policy */ 2N/A pkiDebug(
"client sent dh params with %d bits, we require %d\n",
2N/A /* check dhparams is group 2 */ 2N/A /* check dhparams is group 14 */ 2N/A /* check dhparams is group 16 */ 2N/A/* kdc's dh function */ 2N/A /* Solaris Kerberos */ 2N/A /* get client's received DH parameters that we saved in server_check_dh */ 2N/A /* decode client's public key */ 2N/A /* generate DH session key */ 2N/A /* pack DH public key */ 2N/A /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this 2N/A * encoding shall be used as the contents (the value) of the 2N/A * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo 2N/A * Add locking around did_init to make it MT-safe. 2N/A /* initialize openssl routines */ 2N/A pkiDebug(
"encode_krb5_td_trusted_certifiers failed\n");
2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A pkiDebug(
"client sent %d DH bits server prefers %d DH bits\n",
2N/A pkiDebug(
"DH parameters provided by server are unacceptable\n");
2N/A * Delay creating this OID until we know we need it. 2N/A * It shadows an existing OpenSSL oid. If it 2N/A * is created too early, it breaks things like 2N/A * the use of pkcs12 (which uses pkcs7 structures). 2N/A * We need this shadow version because our code 2N/A * depends on the "other" type to be unknown to the 2N/A pkiDebug(
"%s: Creating shadow instance of pkcs7-data oid\n",
2N/A * This is a version that worked with Longhorn Beta 3. 2N/A pkiDebug(
"%s: This is the Longhorn version and is_longhorn_server = %d\n",
2N/A /* Get length to wrap the original data with SEQUENCE tag */ 2N/A /* Add the signedData OID and adjust lengths */ 2N/A * This is a version that works with a patched Longhorn KDC. 2N/A * (Which should match SP1 ??). 2N/A pkiDebug(
"%s: This is the Longhorn version and is_longhorn_server = %d\n",
2N/A /* New longhorn is missing another sequence */ 2N/A /* Get length to wrap the original data with SEQUENCE tag */ 2N/A /* Always add oid */ 2N/A /* Wrap in extra seq tag */ 2N/A /* Get length to wrap the original data with SEQUENCE tag */ 2N/A /* Add the signedData OID and adjust lengths */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A * Solaris Kerberos: this is a new function that does not exist yet in the MIT 2N/A * labelstr will be C string containing token label with trailing white space 2N/A * \0 terminate labelstr in case the last char in the token label is 2N/A /* init i so terminating \0 is skipped */ 2N/A * Solaris Kerberos: this is a new function that does not exist yet in the MIT 2N/A * Note, assuming this type for now, may need to be passed in in the future. 2N/A /* PROMPTER_INVOCATION */ 2N/A * Solaris Kerberos: this function was changed to support a PIN being passed 2N/A * in. If that is the case the user will not be prompted for their PIN. 2N/A * Don't include NULL string terminator in length calculation as this 2N/A * PIN is passed to the C_Login function and only the text chars should 2N/A * be considered to be the PIN. 2N/A /* Solaris Kerberos - trim token label */ 2N/A pkiDebug(
"pkinit_login: id_cryptoctx->prompter is NULL\n");
2N/A /* Solaris Kerberos: Improved error messages */ 2N/A gettext(
"Failed to log into token: prompter function is NULL"));
2N/A /* Solaris Kerberos - Changes for gettext() */ 2N/A /* Solaris Kerberos - trim token label which can be padded with space */ 2N/A /* Solaris Kerberos */ 2N/A * Note that the prompter function will set rdat.length such that the 2N/A * NULL terminator is not included 2N/A /* PROMPTER_INVOCATION */ 2N/A /* Solaris Kerberos: Improved error messages */ 2N/A /* Solaris Kerberos: only need to login once */ 2N/A * Solaris Kerberos: added these structs in support of prompting user for 2N/A * Solaris Kerberos: this is a new function that does not exist yet in the MIT 2N/A "Press enter to continue");
2N/A /* note, don't care about the reply */ 2N/A * Solaris Kerberos: new defines for prompting support. 2N/A * Solaris Kerberos: this is a new function that does not exist yet in the MIT 2N/A * This prompts to user for various choices regarding a token to use. Note 2N/A * that if there is no error, choice will be set to one of: 2N/A * - the token_choices->token_array entry 2N/A * Assuming that PAM_MAX_MSG_SIZE is a reasonable restriction. Note that - 2N/A * 2 is to account for the fact that a krb prompter to PAM conv bridge will 2N/A /* Create the menu prompt */ 2N/A /* only need to do this once before the for loop */ 2N/A "%s\n%d: %s \"%s\" %s %d\n%d: %s\n%d: %s\n",
2N/A * TRANSLATION_NOTE: Translations of the 2N/A * following 5 strings must not exceed 450 2N/A gettext(
"Select one of the following and press enter:"),
2N/A pkiDebug(
"pkinit_choose_tokens: buffer overflow num_used: %d," 2N/A " %d exceeds prompt buffer size %d"),
2N/A gettext(
"Error: PKINIT prompt message is too large for buffer, " 2N/A "please alert the system administrator. Press enter to " 2N/A "%s\n%d: %s \"%s\" %s %d\n%d: %s\n%d: %s\n%d: %s\n",
2N/A * TRANSLATION_NOTE: Translations of the 2N/A * following 6 strings must not exceed 445 2N/A gettext(
"Select one of the following and press enter:"),
2N/A pkiDebug(
"pkinit_choose_tokens: buffer overflow num_used: %d," 2N/A " %d exceeds prompt buffer size %d"),
2N/A gettext(
"Error: PKINIT prompt message is too large for buffer, " 2N/A "please alert the system administrator. Press enter to " 2N/A * reply.length needs to be reset to length of tmpbuf before calling 2N/A /* reply better be digits */ 2N/A *
choice = i;
/* chosen entry of token_choices->token_array */ 2N/A * Solaris Kerberos: this is a new function that does not exist yet in the MIT 2N/A * Note, this isn't the best solution to providing a function to check the 2N/A * certs in a token however I wanted to avoid rewriting a bunch of code so I 2N/A * settled for some duplication of processing. 2N/A /* If a cert id and/or label were given, use them too */ 2N/A gettext(
"PKCS11 error from C_FindObjectsInit: %s"),
2N/A for (i = 0; ; i++) {
2N/A /* Look for x.509 cert */ 2N/A /* Solaris Kerberos */ 2N/A /* Get cert and id len */ 2N/A gettext(
"Error from PKCS11 C_GetAttributeValue: %s"),
2N/A /* Read the cert and id off the card */ 2N/A gettext(
"Error from PKCS11 C_GetAttributeValue: %s"),
2N/A * Do not let pkinit_cert_matching set the primary cert in id_cryptoctx 2N/A * as this will be done later. 2N/A * If there's an error or load_cert isn't 1 free all the certs loaded 2N/A * onto id_cryptoctx. 2N/A * Solaris Kerberos: this function has been significantly modified to prompt 2N/A * the user in certain cases so defer to this version when resyncing MIT code. 2N/A * pkinit_open_session now does several things including prompting the user if 2N/A * do_matching is set which indicates the code is executing in a client 2N/A * context. This function fills out a pkinit_identity_crypto_context with a 2N/A * set of certs and a open session if a token can be found that matches all 2N/A * supplied criteria. If no token is found then the user is prompted one time 2N/A * to insert their token. If there is more than one token that matches all 2N/A * client criteria the user is prompted to make a choice if in client context. 2N/A * If do_matching is false (KDC context) then the first token matching all 2N/A * server criteria is chosen. 2N/A return 0;
/* session already open */ 2N/A /* Solaris Kerberos: Don't fail if cryptoki is already initialized */ 2N/A * If C_Initialize was already called by the process before the pkinit 2N/A * module was loaded then record that fact. 2N/A * "finalize_pkcs11" is used by pkinit_fini_pkcs11 to determine whether 2N/A * or not C_Finalize() should be called. 2N/A * First make sure that is an applicable slot otherwise fail. 2N/A * Start by getting a count of all slots with or without tokens. 2N/A gettext(
"Error trying to get PKCS11 slot list: %s"),
2N/A /* There are no slots so bail */ 2N/A /* See if any of the slots match the specified slotID */ 2N/A gettext(
"Error trying to get PKCS11 slot list: %s"),
2N/A /* no slots match */ 2N/A pkiDebug(
"open_session: no matching slot found for slotID %d\n",
2N/A /* get count of slots that have tokens */ 2N/A gettext(
"Error trying to get PKCS11 slot list: %s"),
2N/A * Note, never prompt if !do_matching as this implies KDC side 2N/A /* found slot(s) but no token so prompt and try again */ 2N/A /* already prompted once so bailing */ 2N/A pkiDebug(
"pkinit_open_session: no token, already prompted\n");
2N/A * Solaris Kerberos: get list of PKCS11 slotid's that have tokens. 2N/A gettext(
"Error trying to get PKCS11 slot list: %s"),
2N/A /* examine all the tokens */ 2N/A * Solaris Kerberos: if a slotid was specified skip slots that don't 2N/A gettext(
"Error trying to open PKCS11 session: %s"),
2N/A /* Get token info */ 2N/A * If the token doesn't require login to examine the certs then 2N/A * let's check the certs out to see if any match the criteria if 2N/A * It's okay to check the certs if we don't have to login but 2N/A * don't load the certs onto cctx at this point, this will be 2N/A * done later in this function for the chosen token. 2N/A /* ignore ENOENT here */ 2N/A /* + 1 so tokenlabelstr can be \0 terminated */ 2N/A * Convert token label into C string with trailing white space 2N/A pkiDebug(
"open_session: slotid %d token found: \"%s\", " 2N/A "cctx->token_label: \"%s\"\n",
2N/A * It's okay to check the certs if we don't have to login but 2N/A * don't load the certs onto cctx at this point, this will be 2N/A * done later in this function for the chosen token. 2N/A /* ignore ENOENT here */ 2N/A /* !do_matching implies we take the first matching token */ 2N/A * Solaris Kerberos: prompt for token one time if there was no token 2N/A * and do_matching is 1 (see earlier comment about do_matching). 2N/A pkiDebug(
"pkinit_open_session: pkinit_choose_tokens failed: %d\n", r);
2N/A /* close all sessions */ 2N/A choice = 0;
/* really the only choice is the first token_array entry */ 2N/A /* > 1 token so present menu of token choices, let the user decide. */ 2N/A pkiDebug(
"pkinit_open_session: pkinit_choose_tokens failed: %d\n", r);
2N/A /* close all sessions */ 2N/A /* Login if needed */ 2N/A /* Solaris Kerberos: added cctx->p11flags check */ 2N/A /* Doing this again to load the certs into cctx. */ 2N/A /* close all sessions if there's an error */ 2N/A /* close sessions not chosen */ 2N/A * Look for a key that's: 2N/A * 2. capable of the specified operation (usually signing or decrypting) 2N/A * 3. RSA (this may be wrong but it's all we can do for now) 2N/A * 4. matches the id of the cert we chose 2N/A * You must call pkinit_get_certs before calling pkinit_find_private_key 2N/A * (that's because we need the ID of the private key) 2N/A * pkcs11 says the id of the key doesn't have to match that of the cert, but 2N/A * I can't figure out any other way to decide which key to use. 2N/A * We should only find one key that fits all the requirements. 2N/A * If there are more than one, we just take the first one. 2N/A * Some cards get confused if you try to specify a key usage, 2N/A * so don't, and hope for the best. This will fail if you have 2N/A * several keys with the same id and different usages but I have 2N/A * not seen this on real cards. 2N/A pkiDebug(
"krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
2N/A * The CKA_ID may not be correctly set for the private key. For e.g. when 2N/A * storing a private key in softtoken pktool(1) doesn't generate or store 2N/A * a CKA_ID for the private key. Another way to identify the private key is 2N/A * to look for a private key with the same RSA modulus as the public key 2N/A * in the certificate. 2N/A pkiDebug(
"krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
2N/A * Solaris Kerberos: assume session is open and libpkcs11 funcs have been 2N/A /* Solaris Kerberos: Login, if needed, to access private object */ 2N/A pkiDebug(
"session %x edata %x edata_len %d data %x datalen @%x %d\n",
2N/A * Solaris Kerberos: assume session is open and libpkcs11 funcs have been 2N/A /* Solaris Kerberos: Login, if needed, to access private object */ 2N/A * Key len would give an upper bound on sig size, but there's no way to 2N/A * get that. So guess, and if it's too small, re-malloc. 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A * This is not the routine the KDC uses to get its certificate. 2N/A * This routine is intended to be called by the client 2N/A * to obtain the KDC's certificate from some local storage 2N/A * to be sent as a hint in its request to the KDC. 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos: Improved error messages */ 2N/A /* Solaris Kerberos: Improved error messages */ 2N/A /* Solaris Kerberos: Improved error messages */ 2N/A pkiDebug(
"Failed to open PKCS12 file '%s', error %d\n",
2N/A gettext(
"Failed to decode PKCS12 file '%s' contents"),
2N/A pkiDebug(
"Failed to decode PKCS12 file '%s' contents\n",
2N/A * Try parsing with no pass phrase first. If that fails, 2N/A * prompt for the pass phrase and try again. 2N/A /* Solaris Kerberos */ 2N/A pkiDebug(
"Initial PKCS12_parse with no password failed\n");
2N/A /* Solaris Kerberos: use PIN if set */ 2N/A /* note rdat.length isn't needed in this case */ 2N/A /* PROMPTER_INVOCATION */ 2N/A /* Solaris Kerberos: Improved error messages */ 2N/A gettext(
"Failed to parse PKCS12 file '%s' with password"),
2N/A pkiDebug(
"Seconde PKCS12_parse with password failed\n");
2N/A /* load the certificate */ 2N/A /* Solaris Kerberos: Improved error messages */ 2N/A gettext(
"Failed to load user's certificate from %s: %s"),
2N/A /* Solaris Kerberos: Improved error messages */ 2N/A gettext(
"Failed to load user's private key from %s: %s"),
2N/A pkiDebug(
"%s: failed to get user's private key location\n",
2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A pkiDebug(
"%s: failed to get user's certificate directory location\n",
2N/A /* Solaris Kerberos: Improved error messages */ 2N/A * We'll assume that certs are named XXX.crt and the corresponding 2N/A * key is named XXX.key 2N/A /* Ignore subdirectories and anything starting with a dot */ 2N/A /* Checked length */ 2N/A pkiDebug(
"%s: Path too long -- directory '%s' and file '%s'\n",
2N/A pkiDebug(
"%s: Successfully loaded cert (and key) for %s\n",
2N/A /* Solaris Kerberos: Improved error messages */ 2N/A /* Copy stuff from idopts -> id_cryptoctx */ 2N/A /* Convert the ascii cert_id string into a binary blob */ 2N/A * If the cert_id_string is empty then behave in a similar way to how 2N/A * an empty certlabel is treated - i.e. don't fail now but rather continue 2N/A * as though the certid wasn't specified. 2N/A * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but 2N/A * many cards seems to be confused about whether they are capable of 2N/A * this or not. The safe thing seems to be to ignore the mechanism list, 2N/A * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves. 2N/A /* This seems backwards... */ 2N/A/* Solaris Kerberos */ 2N/A * Get number of certificates available after crypto_load_certs() 2N/A * Begin iteration over the certs loaded in crypto_load_certs() 2N/A * End iteration over the certs loaded in crypto_load_certs() 2N/A * Get next certificate handle 2N/A * Release cert handle 2N/A * Get certificate Key Usage and Extended Key Usage 2N/A /* Solaris Kerberos */ 2N/A /* Start with Extended Key usage */ 2N/A /* Now the Key Usage bits */ 2N/A /* Make sure usage exists before checking bits */ 2N/A * Return a string format of an X509_NAME in buf where 2N/A * size is an in/out parameter. On input it is the size 2N/A * of the buffer, and on output it is the actual length 2N/A * If buf is NULL, returns the length req'd to hold name 2N/A * Get certificate information 2N/A /* get the subject name (in rfc2253 format) */ 2N/A /* get the issuer name (in rfc2253 format) */ 2N/A /* get the san data */ 2N/A /* get the KU and EKU data */ 2N/A * Free certificate information 2N/A * Make this matching certificate "the chosen one" 2N/A /* copy the selected cert into our id_cryptoctx */ 2N/A * Choose the default certificate as "the chosen one" 2N/A /* Solaris Kerberos: Improved error messages */ 2N/A "found %d certs to choose from but there must be exactly one"),
2N/A pkiDebug(
"%s: ERROR: There are %d certs to choose from, " 2N/A "but there must be exactly one.\n",
2N/A /* copy the selected cert into our id_cryptoctx */ 2N/A /* Solaris Kerberos */ 2N/A /* If there isn't already a stack in the context, 2N/A * create a temporary one now */ 2N/A /* scan over the stack created from loading the file contents, 2N/A * weed out duplicates, and push new ones onto the return stack 2N/A /* If we added something and there wasn't a stack in the 2N/A * context before, add the temporary stack to the context. 2N/A /* Should have been caught above! */ 2N/A /* Solaris Kerberos: removed "break" as it's never reached */ 2N/A pkiDebug(
"%s: Path too long -- directory '%s' and file '%s'\n",
2N/A /* Ignore subdirectories and anything starting with a dot */ 2N/A /* Solaris Kerberos: Removed "break"'s as they are never reached */ 2N/A /* fill-in subjectName */ 2N/A /* fill-in issuerAndSerialNumber */ 2N/Aif (
longhorn == 0) {
/* XXX Longhorn doesn't like this */ 2N/A /* fill-in subjectKeyIdentifier */ 2N/Aif (
longhorn == 0) {
/* XXX Longhorn doesn't like this */ 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A/* Solaris Kerberos: Suppress sun studio compiler warning */ 2N/A pkiDebug(
"#%d issuer = %s serial = %ld is trusted bu kdc\n", i,
2N/A /* XXX Since we not doing anything with received trusted certifiers 2N/A * return an error. this is the place where we can pick a different 2N/A * client certificate based on the information in td_trusted_certifiers 2N/A/* Solaris Kerberos: Not used */ 2N/A/* Solaris Kerberos: Not used */ 2N/A /* It was encrypted, we need to decrypt the secret key 2N/A * with the private key */ 2N/A /* Find the recipientInfo which matches the passed certificate 2N/A /* If we haven't got a certificate try each ri in turn */ 2N/A /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */ 2N/A /* Some S/MIME clients don't use the same key 2N/A * and effective key length. The key length is 2N/A * determined by the size of the decrypted RSA key. 2N/A /* Solaris Kerberos */ 2N/A /* Solaris Kerberos */ 2N/A * Error message generation has changed so gettext() can be used