Print this page
8982 Support building with OpenSSL 1.1


  14  * portion of this software, then the disclaimer below must
  15  * also be included.
  16  *
  17  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
  18  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
  19  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
  20  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
  21  * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
  22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
  23  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
  24  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
  25  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
  26  * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
  27  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
  28  * SUCH DAMAGES.
  29  */
  30 
  31 /*
  32  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  33  * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.

  34  */
  35 
  36 #include <errno.h>
  37 #include <string.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <dlfcn.h>
  41 #include <unistd.h>
  42 #include <dirent.h>
  43 
  44 
  45 /* Solaris Kerberos */
  46 #include <libintl.h>
  47 #include <assert.h>
  48 #include <security/pam_appl.h>
  49 #include <ctype.h>
  50 #include "k5-int.h"
  51 #include <ctype.h>
  52 
  53 /*


 352     0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
 353     0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
 354     0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
 355     0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
 356     0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
 357     0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
 358     0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
 359     0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
 360     0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
 361     0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
 362     0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
 363     0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
 364     0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
 365     0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
 366     0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
 367     0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
 368     0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
 369     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 370 };
 371 































































































 372 /* Solaris Kerberos */
 373 static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
 374 static int pkinit_oids_refs = 0;
 375 
 376 krb5_error_code
 377 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
 378 
 379     krb5_error_code retval = ENOMEM;
 380     pkinit_plg_crypto_context ctx = NULL;
 381 
 382     /* initialize openssl routines */
 383     /* Solaris Kerberos */
 384     retval = openssl_init();
 385     if (retval != 0)
 386         goto out;
 387 
 388     ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
 389     if (ctx == NULL)
 390         goto out;
 391     (void) memset(ctx, 0, sizeof(*ctx));


 639         pkiDebug("failed to read private key from %s\n", filename);
 640         goto cleanup;
 641     }
 642     *retkey = pkey;
 643     retval = 0;
 644 cleanup:
 645     if (tmp != NULL)
 646         BIO_free(tmp);
 647     return retval;
 648 }
 649 
 650 static void
 651 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
 652 {
 653     if (ctx == NULL)
 654         return;
 655 
 656     /* Only call OBJ_cleanup once! */
 657     /* Solaris Kerberos: locking */
 658     k5_mutex_lock(&oids_mutex);






 659     if (--pkinit_oids_refs == 0)
 660         OBJ_cleanup();



 661     k5_mutex_unlock(&oids_mutex);
 662 }
 663 































 664 static krb5_error_code
 665 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
 666 {
 667     krb5_error_code retval = ENOMEM;
 668 
 669     plgctx->dh_1024 = DH_new();

 670     if (plgctx->dh_1024 == NULL)
 671         goto cleanup;
 672     plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
 673         sizeof(pkinit_1024_dhprime), NULL);
 674     if ((plgctx->dh_1024->g = BN_new()) == NULL ||
 675         (plgctx->dh_1024->q = BN_new()) == NULL)
 676         goto cleanup;
 677     BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
 678     BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
 679 
 680     plgctx->dh_2048 = DH_new();

 681     if (plgctx->dh_2048 == NULL)
 682         goto cleanup;
 683     plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime,
 684         sizeof(pkinit_2048_dhprime), NULL);
 685     if ((plgctx->dh_2048->g = BN_new()) == NULL ||
 686         (plgctx->dh_2048->q = BN_new()) == NULL)
 687         goto cleanup;
 688     BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2);
 689     BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p);
 690 
 691     plgctx->dh_4096 = DH_new();

 692     if (plgctx->dh_4096 == NULL)
 693         goto cleanup;
 694     plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime,
 695         sizeof(pkinit_4096_dhprime), NULL);
 696     if ((plgctx->dh_4096->g = BN_new()) == NULL ||
 697         (plgctx->dh_4096->q = BN_new()) == NULL)
 698         goto cleanup;
 699     BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2);
 700     BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p);
 701 
 702     retval = 0;
 703 
 704 cleanup:
 705     if (retval)
 706         pkinit_fini_dh_params(plgctx);
 707 
 708     return retval;
 709 }
 710 
 711 static void
 712 pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
 713 {
 714     if (plgctx->dh_1024 != NULL)
 715         DH_free(plgctx->dh_1024);
 716     if (plgctx->dh_2048 != NULL)
 717         DH_free(plgctx->dh_2048);
 718     if (plgctx->dh_4096 != NULL)
 719         DH_free(plgctx->dh_4096);
 720 


 841 cms_signeddata_create(krb5_context context,
 842                       pkinit_plg_crypto_context plg_cryptoctx,
 843                       pkinit_req_crypto_context req_cryptoctx,
 844                       pkinit_identity_crypto_context id_cryptoctx,
 845                       int cms_msg_type,
 846                       int include_certchain,
 847                       unsigned char *data,
 848                       unsigned int data_len,
 849                       unsigned char **signed_data,
 850                       unsigned int *signed_data_len)
 851 {
 852     /* Solaris Kerberos */
 853     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
 854     PKCS7  *p7 = NULL, *inner_p7 = NULL;
 855     PKCS7_SIGNED *p7s = NULL;
 856     PKCS7_SIGNER_INFO *p7si = NULL;
 857     unsigned char *p;
 858     ASN1_TYPE *pkinit_data = NULL;
 859     STACK_OF(X509) * cert_stack = NULL;
 860     ASN1_OCTET_STRING *digest_attr = NULL;
 861     EVP_MD_CTX ctx, ctx2;
 862     const EVP_MD *md_tmp = NULL;
 863     unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
 864     unsigned char *digestInfo_buf = NULL, *abuf = NULL;
 865     unsigned int md_len, md_len2, alen, digestInfo_len;
 866     STACK_OF(X509_ATTRIBUTE) * sk;
 867     unsigned char *sig = NULL;
 868     unsigned int sig_len = 0;
 869     X509_ALGOR *alg = NULL;
 870     ASN1_OCTET_STRING *digest = NULL;
 871     unsigned int alg_len = 0, digest_len = 0;
 872     unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
 873     X509 *cert = NULL;
 874     ASN1_OBJECT *oid = NULL;
 875 
 876     /* Solaris Kerberos */
 877     if (signed_data == NULL)
 878         return EINVAL;
 879 
 880     if (signed_data_len == NULL)
 881         return EINVAL;


 885         goto cleanup;
 886     p7->type = OBJ_nid2obj(NID_pkcs7_signed);
 887 
 888     if ((p7s = PKCS7_SIGNED_new()) == NULL)
 889         goto cleanup;
 890     p7->d.sign = p7s;
 891     if (!ASN1_INTEGER_set(p7s->version, 3))
 892         goto cleanup;
 893 
 894     /* create a cert chain that has at least the signer's certificate */
 895     if ((cert_stack = sk_X509_new_null()) == NULL)
 896         goto cleanup;
 897 
 898     cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
 899     if (!include_certchain) {
 900         pkiDebug("only including signer's certificate\n");
 901         sk_X509_push(cert_stack, X509_dup(cert));
 902     } else {
 903         /* create a cert chain */
 904         X509_STORE *certstore = NULL;
 905         X509_STORE_CTX certctx;
 906         STACK_OF(X509) *certstack = NULL;
 907         char buf[DN_BUF_LEN];
 908         int i = 0, size = 0;
 909 
 910         if ((certstore = X509_STORE_new()) == NULL)
 911             goto cleanup;


 912         pkiDebug("building certificate chain\n");
 913         X509_STORE_set_verify_cb_func(certstore, openssl_callback);
 914         X509_STORE_CTX_init(&certctx, certstore, cert,
 915                             id_cryptoctx->intermediateCAs);
 916         X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
 917         /* Solaris Kerberos */
 918         if (X509_verify_cert(&certctx) <= 0) {
 919             pkiDebug("failed to create a certificate chain: %s\n", 
 920             X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
 921             if (!sk_X509_num(id_cryptoctx->trustedCAs)) 
 922                 pkiDebug("No trusted CAs found. Check your X509_anchors\n");
 923             goto cleanup;
 924         }
 925         certstack = X509_STORE_CTX_get1_chain(&certctx);
 926         size = sk_X509_num(certstack);
 927         pkiDebug("size of certificate chain = %d\n", size);
 928         for(i = 0; i < size - 1; i++) {
 929             X509 *x = sk_X509_value(certstack, i);
 930             X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
 931             pkiDebug("cert #%d: %s\n", i, buf);
 932             sk_X509_push(cert_stack, X509_dup(x));
 933         }
 934         X509_STORE_CTX_cleanup(&certctx);
 935         X509_STORE_free(certstore);
 936         sk_X509_pop_free(certstack, X509_free);
 937     }
 938     p7s->cert = cert_stack;
 939 
 940     /* fill-in PKCS7_SIGNER_INFO */
 941     if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
 942         goto cleanup;
 943     if (!ASN1_INTEGER_set(p7si->version, 1))
 944         goto cleanup;
 945     if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
 946                        X509_get_issuer_name(cert)))
 947         goto cleanup;
 948     /* because ASN1_INTEGER_set is used to set a 'long' we will do
 949      * things the ugly way. */
 950     M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
 951     if (!(p7si->issuer_and_serial->serial =
 952           M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
 953         goto cleanup;
 954 
 955     /* will not fill-out EVP_PKEY because it's on the smartcard */
 956 
 957     /* Set digest algs */
 958     p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
 959 
 960     if (p7si->digest_alg->parameter != NULL)
 961         ASN1_TYPE_free(p7si->digest_alg->parameter);
 962     if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
 963         goto cleanup;
 964     p7si->digest_alg->parameter->type = V_ASN1_NULL;
 965 
 966     /* Set sig algs */
 967     if (p7si->digest_enc_alg->parameter != NULL)
 968         ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
 969     p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
 970     if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
 971         goto cleanup;
 972     p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
 973 
 974     /* pick the correct oid for the eContentInfo */
 975     oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
 976     if (oid == NULL)
 977         goto cleanup;
 978 
 979     if (cms_msg_type == CMS_SIGN_DRAFT9) {
 980         /* don't include signed attributes for pa-type 15 request */
 981         abuf = data;
 982         alen = data_len;
 983     } else {
 984         /* add signed attributes */
 985         /* compute sha1 digest over the EncapsulatedContentInfo */
 986         EVP_MD_CTX_init(&ctx);
 987         EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
 988         EVP_DigestUpdate(&ctx, data, data_len);
 989         md_tmp = EVP_MD_CTX_md(&ctx);
 990         EVP_DigestFinal_ex(&ctx, md_data, &md_len);





 991 
 992         /* create a message digest attr */
 993         digest_attr = ASN1_OCTET_STRING_new();
 994         ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
 995         PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
 996                                    V_ASN1_OCTET_STRING, (char *) digest_attr);
 997 
 998         /* create a content-type attr */
 999         PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, 
1000                                    V_ASN1_OBJECT, oid);
1001 
1002         /* create the signature over signed attributes. get DER encoded value */
1003         /* This is the place where smartcard signature needs to be calculated */
1004         sk = p7si->auth_attr;
1005         alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
1006                              ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
1007         if (abuf == NULL)
1008             goto cleanup2;
1009     }
1010 
1011 #ifndef WITHOUT_PKCS11
1012     /* Some tokens can only do RSAEncryption without sha1 hash */
1013     /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
1014      * function and the hash value into an ASN.1 value of type DigestInfo
1015      * DigestInfo::=SEQUENCE {
1016      *  digestAlgorithm  AlgorithmIdentifier,
1017      *  digest OCTET STRING }
1018      */
1019     if (id_cryptoctx->pkcs11_method == 1 && 
1020             id_cryptoctx->mech == CKM_RSA_PKCS) {
1021         pkiDebug("mech = CKM_RSA_PKCS\n");
1022         EVP_MD_CTX_init(&ctx2);



1023         /* if this is not draft9 request, include digest signed attribute */
1024         if (cms_msg_type != CMS_SIGN_DRAFT9) 
1025             EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
1026         else
1027             EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
1028         EVP_DigestUpdate(&ctx2, abuf, alen);
1029         EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);


1030 
1031         alg = X509_ALGOR_new();
1032         if (alg == NULL)
1033             goto cleanup2;
1034         alg->algorithm = OBJ_nid2obj(NID_sha1);
1035         alg->parameter = NULL;
1036         alg_len = i2d_X509_ALGOR(alg, NULL);
1037         alg_buf = (unsigned char *)malloc(alg_len);
1038         if (alg_buf == NULL)
1039             goto cleanup2;
1040 
1041         digest = ASN1_OCTET_STRING_new();
1042         if (digest == NULL)
1043             goto cleanup2;
1044         ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
1045         digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
1046         digest_buf = (unsigned char *)malloc(digest_len);
1047         if (digest_buf == NULL)
1048             goto cleanup2;
1049 


1143     }
1144     retval = 0;
1145 
1146 #ifdef DEBUG_ASN1
1147     if (cms_msg_type == CMS_SIGN_CLIENT) {
1148         print_buffer_bin(*signed_data, *signed_data_len,
1149                          "/tmp/client_pkcs7_signeddata");
1150     } else {
1151         if (cms_msg_type == CMS_SIGN_SERVER) {
1152             print_buffer_bin(*signed_data, *signed_data_len,
1153                              "/tmp/kdc_pkcs7_signeddata");
1154         } else {
1155             print_buffer_bin(*signed_data, *signed_data_len,
1156                              "/tmp/draft9_pkcs7_signeddata");
1157         }
1158     }
1159 #endif
1160 
1161   cleanup2:
1162     if (cms_msg_type != CMS_SIGN_DRAFT9) 
1163         EVP_MD_CTX_cleanup(&ctx);

1164 #ifndef WITHOUT_PKCS11
1165     if (id_cryptoctx->pkcs11_method == 1 && 
1166             id_cryptoctx->mech == CKM_RSA_PKCS) {
1167         EVP_MD_CTX_cleanup(&ctx2);

1168         if (digest_buf != NULL)
1169             free(digest_buf);
1170         if (digestInfo_buf != NULL)
1171             free(digestInfo_buf);
1172         if (alg_buf != NULL)
1173             free(alg_buf);
1174         if (digest != NULL)
1175             ASN1_OCTET_STRING_free(digest);
1176     }
1177 #endif
1178     if (alg != NULL)
1179         X509_ALGOR_free(alg);
1180   cleanup:
1181     if (p7 != NULL) 
1182         PKCS7_free(p7);
1183     if (sig != NULL)
1184         free(sig);
1185 
1186     return retval;
1187 }


1193                       pkinit_identity_crypto_context idctx,
1194                       int cms_msg_type,
1195                       int require_crl_checking,
1196                       unsigned char *signed_data,
1197                       unsigned int signed_data_len,
1198                       unsigned char **data,
1199                       unsigned int *data_len,
1200                       unsigned char **authz_data,
1201                       unsigned int *authz_data_len)
1202 {
1203     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
1204     PKCS7 *p7 = NULL;
1205     BIO *out = NULL;
1206     int flags = PKCS7_NOVERIFY, i = 0;
1207     unsigned int vflags = 0, size = 0;
1208     const unsigned char *p = signed_data;
1209     STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
1210     PKCS7_SIGNER_INFO *si = NULL;
1211     X509 *x = NULL;
1212     X509_STORE *store = NULL;
1213     X509_STORE_CTX cert_ctx;
1214     STACK_OF(X509) *intermediateCAs = NULL;
1215     STACK_OF(X509_CRL) *revoked = NULL;
1216     STACK_OF(X509) *verified_chain = NULL;
1217     ASN1_OBJECT *oid = NULL;
1218     krb5_external_principal_identifier **krb5_verified_chain = NULL;
1219     krb5_data *authz = NULL;
1220     char buf[DN_BUF_LEN];
1221 
1222 #ifdef DEBUG_ASN1
1223     print_buffer_bin(signed_data, signed_data_len,
1224                      "/tmp/client_received_pkcs7_signeddata");
1225 #endif
1226 
1227     /* Do this early enough to create the shadow OID for pkcs7-data if needed */
1228     oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
1229     if (oid == NULL)
1230         goto cleanup;
1231 
1232     /* decode received PKCS7 message */
1233     if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {


1237         pkiDebug("%s: failed to decode message: %s\n",
1238                  __FUNCTION__, ERR_error_string(err, NULL));
1239         goto cleanup;
1240     }
1241 
1242     /* verify that the received message is PKCS7 SignedData message */
1243     if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
1244         pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
1245                  OBJ_obj2nid(p7->type));
1246         krb5_set_error_message(context, retval, "wrong oid\n");
1247         goto cleanup;
1248     }
1249 
1250     /* setup to verify X509 certificate used to sign PKCS7 message */
1251     if (!(store = X509_STORE_new()))
1252         goto cleanup;
1253 
1254     /* check if we are inforcing CRL checking */
1255     vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
1256     if (require_crl_checking)
1257         X509_STORE_set_verify_cb_func(store, openssl_callback);
1258     else
1259         X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
1260     X509_STORE_set_flags(store, vflags);
1261 
1262     /* get the signer's information from the PKCS7 message */
1263     if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
1264         goto cleanup;
1265     if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
1266         goto cleanup;
1267     if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
1268         goto cleanup;
1269 
1270     /* create available CRL information (get local CRLs and include CRLs
1271      * received in the PKCS7 message
1272      */
1273     if (idctx->revoked == NULL)
1274         revoked = p7->d.sign->crl;
1275     else if (p7->d.sign->crl == NULL)
1276         revoked = idctx->revoked;
1277     else {
1278         size = sk_X509_CRL_num(idctx->revoked);
1279         revoked = sk_X509_CRL_new_null();


1290     if (idctx->intermediateCAs == NULL)
1291         intermediateCAs = p7->d.sign->cert;
1292     else if (p7->d.sign->cert == NULL)
1293         intermediateCAs = idctx->intermediateCAs;
1294     else {
1295         size = sk_X509_num(idctx->intermediateCAs);
1296         intermediateCAs = sk_X509_new_null();
1297         for (i = 0; i < size; i++) {
1298             sk_X509_push(intermediateCAs,
1299                 sk_X509_value(idctx->intermediateCAs, i));
1300         }
1301         size = sk_X509_num(p7->d.sign->cert);
1302         for (i = 0; i < size; i++) {
1303             sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
1304         }
1305     }
1306 
1307     /* initialize x509 context with the received certificate and
1308      * trusted and intermediate CA chains and CRLs
1309      */
1310     if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs))
1311         goto cleanup;


1312 
1313     X509_STORE_CTX_set0_crls(&cert_ctx, revoked);
1314 
1315     /* add trusted CAs certificates for cert verification */
1316     if (idctx->trustedCAs != NULL)
1317         X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs);
1318     else {
1319         pkiDebug("unable to find any trusted CAs\n");
1320         goto cleanup;
1321     }
1322 #ifdef DEBUG_CERTCHAIN
1323     if (intermediateCAs != NULL) {
1324         size = sk_X509_num(intermediateCAs);
1325         pkiDebug("untrusted cert chain of size %d\n", size);
1326         for (i = 0; i < size; i++) {
1327             X509_NAME_oneline(X509_get_subject_name(
1328                 sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
1329             pkiDebug("cert #%d: %s\n", i, buf);
1330         }
1331     }
1332     if (idctx->trustedCAs != NULL) {
1333         size = sk_X509_num(idctx->trustedCAs);
1334         pkiDebug("trusted cert chain of size %d\n", size);
1335         for (i = 0; i < size; i++) {
1336             X509_NAME_oneline(X509_get_subject_name(
1337                 sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
1338             pkiDebug("cert #%d: %s\n", i, buf);
1339         }
1340     }
1341     if (revoked != NULL) {
1342         size = sk_X509_CRL_num(revoked);
1343         pkiDebug("CRL chain of size %d\n", size);
1344         for (i = 0; i < size; i++) {
1345             X509_CRL *crl = sk_X509_CRL_value(revoked, i);
1346             X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
1347             pkiDebug("crls by CA #%d: %s\n", i , buf);
1348         }
1349     }
1350 #endif
1351 
1352     i = X509_verify_cert(&cert_ctx);
1353     if (i <= 0) {
1354         int j = X509_STORE_CTX_get_error(&cert_ctx);
1355 
1356         reqctx->received_cert = X509_dup(cert_ctx.current_cert);

1357         switch(j) {
1358             case X509_V_ERR_CERT_REVOKED:
1359                 retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
1360                 break;
1361             case X509_V_ERR_UNABLE_TO_GET_CRL:
1362                 retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN;
1363                 break;
1364             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1365             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1366                 retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE;
1367                 break;
1368             default:
1369                 retval = KRB5KDC_ERR_INVALID_CERTIFICATE;
1370         }
1371         X509_NAME_oneline(X509_get_subject_name(
1372             reqctx->received_cert), buf, sizeof(buf));
1373         pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
1374                  X509_verify_cert_error_string(j));
1375         krb5_set_error_message(context, retval, "%s\n",
1376             X509_verify_cert_error_string(j));
1377 #ifdef DEBUG_CERTCHAIN
1378         size = sk_X509_num(p7->d.sign->cert);
1379         pkiDebug("received cert chain of size %d\n", size);
1380         for (j = 0; j < size; j++) {
1381             X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
1382             X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
1383             pkiDebug("cert #%d: %s\n", j, buf);
1384         }
1385 #endif
1386     } else {
1387         /* retrieve verified certificate chain */
1388         if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) 
1389             verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx);
1390     }
1391     X509_STORE_CTX_cleanup(&cert_ctx);
1392     if (i <= 0)
1393         goto cleanup;
1394 
1395     out = BIO_new(BIO_s_mem());
1396     if (cms_msg_type == CMS_SIGN_DRAFT9)
1397         flags |= PKCS7_NOATTR;
1398     if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
1399         int valid_oid = 0;
1400 
1401         if (!OBJ_cmp(p7->d.sign->contents->type, oid)) 
1402             valid_oid = 1;
1403         else if (cms_msg_type == CMS_SIGN_DRAFT9) {
1404             /*
1405              * Various implementations of the pa-type 15 request use
1406              * different OIDS.  We check that the returned object
1407              * has any of the acceptable OIDs
1408              */
1409             ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
1410             client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
1411             server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
1412             rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
1413             if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
1414                 !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
1415                 !OBJ_cmp(p7->d.sign->contents->type, rsa_oid))
1416                 valid_oid = 1;
1417         }
1418 
1419         if (valid_oid) 
1420             pkiDebug("PKCS7 Verification successful\n");
1421         else {

1422             pkiDebug("wrong oid in eContentType\n");
1423             print_buffer((unsigned char *)p7->d.sign->contents->type->data, 
1424                 (unsigned int)p7->d.sign->contents->type->length);
1425             retval = KRB5KDC_ERR_PREAUTH_FAILED;
1426             krb5_set_error_message(context, retval, "wrong oid\n");
1427             goto cleanup;
1428         }
1429     }
1430     else {
1431         unsigned long err = ERR_peek_error();
1432         switch(ERR_GET_REASON(err)) {
1433             case PKCS7_R_DIGEST_FAILURE:
1434                 retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
1435                 break;
1436             case PKCS7_R_SIGNATURE_FAILURE:
1437             default:
1438                 retval = KRB5KDC_ERR_INVALID_SIG;
1439         }
1440         pkiDebug("PKCS7 Verification failure\n");
1441         krb5_set_error_message(context, retval, "%s\n",
1442                                ERR_error_string(err, NULL));
1443         goto cleanup;
1444     }


2146     }
2147 
2148     return retval;
2149 }
2150 
2151 /* ARGSUSED */
2152 krb5_error_code
2153 client_create_dh(krb5_context context,
2154                  pkinit_plg_crypto_context plg_cryptoctx,
2155                  pkinit_req_crypto_context cryptoctx,
2156                  pkinit_identity_crypto_context id_cryptoctx,
2157                  int dh_size,
2158                  unsigned char **dh_params,
2159                  unsigned int *dh_params_len,
2160                  unsigned char **dh_pubkey,
2161                  unsigned int *dh_pubkey_len)
2162 {
2163     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2164     unsigned char *buf = NULL;
2165     int dh_err = 0;
2166     ASN1_INTEGER *pub_key = NULL;


2167 
2168     if (cryptoctx->dh == NULL) {
2169         if ((cryptoctx->dh = DH_new()) == NULL)
2170             goto cleanup;
2171         if ((cryptoctx->dh->g = BN_new()) == NULL ||
2172             (cryptoctx->dh->q = BN_new()) == NULL)
2173             goto cleanup;
2174 
2175         switch(dh_size) {
2176             case 1024:
2177                 pkiDebug("client uses 1024 DH keys\n");
2178                 cryptoctx->dh->p = get_rfc2409_prime_1024(NULL);

2179                 break;
2180             case 2048:
2181                 pkiDebug("client uses 2048 DH keys\n");
2182                 cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime,
2183                     sizeof(pkinit_2048_dhprime), NULL);
2184                 break;
2185             case 4096:
2186                 pkiDebug("client uses 4096 DH keys\n");
2187                 cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime,
2188                     sizeof(pkinit_4096_dhprime), NULL);
2189                 break;
2190             default:

2191                 goto cleanup;
2192         }
2193 
2194         BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2);
2195         BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p);
2196     }
2197 
2198     DH_generate_key(cryptoctx->dh);


2199 /* Solaris Kerberos */
2200 #ifdef DEBUG
2201     DH_check(cryptoctx->dh, &dh_err);
2202     if (dh_err != 0) {
2203         pkiDebug("Warning: dh_check failed with %d\n", dh_err);
2204         if (dh_err & DH_CHECK_P_NOT_PRIME)
2205             pkiDebug("p value is not prime\n");
2206         if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
2207             pkiDebug("p value is not a safe prime\n");
2208         if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
2209             pkiDebug("unable to check the generator value\n");
2210         if (dh_err & DH_NOT_SUITABLE_GENERATOR)
2211             pkiDebug("the g value is not a generator\n");
2212     }
2213 #endif
2214 #ifdef DEBUG_DH
2215     print_dh(cryptoctx->dh, "client's DH params\n");
2216     print_pubkey(cryptoctx->dh->pub_key, "client's pub_key=");
2217 #endif
2218 
2219     DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err);
2220     if (dh_err != 0) {
2221         pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
2222         goto cleanup;
2223     }
2224 
2225     /* pack DHparams */
2226     /* aglo: usually we could just call i2d_DHparams to encode DH params
2227      * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
2228      */
2229     retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g,
2230         cryptoctx->dh->q, dh_params, dh_params_len);

2231     if (retval)
2232         goto cleanup;
2233 
2234     /* pack DH public key */
2235     /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2236      * encoding shall be used as the contents (the value) of the
2237      * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2238      * data element
2239      */
2240     if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL)
2241         goto cleanup;
2242     *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
2243     if ((buf = *dh_pubkey = (unsigned char *)
2244             malloc((size_t) *dh_pubkey_len)) == NULL) {
2245         retval  = ENOMEM;
2246         goto cleanup;
2247     }
2248     i2d_ASN1_INTEGER(pub_key, &buf);
2249 
2250     if (pub_key != NULL)
2251         ASN1_INTEGER_free(pub_key);
2252 
2253     retval = 0;
2254     return retval;
2255 
2256   cleanup:
2257     if (cryptoctx->dh != NULL)
2258         DH_free(cryptoctx->dh);
2259     cryptoctx->dh = NULL;
2260     if (*dh_params != NULL)
2261         free(*dh_params);
2262     *dh_params = NULL;
2263     if (*dh_pubkey != NULL)
2264         free(*dh_pubkey);
2265     *dh_pubkey = NULL;
2266     if (pub_key != NULL)
2267         ASN1_INTEGER_free(pub_key);
2268 
2269     return retval;
2270 }
2271 
2272 /* ARGSUSED */
2273 krb5_error_code
2274 client_process_dh(krb5_context context,
2275                   pkinit_plg_crypto_context plg_cryptoctx,
2276                   pkinit_req_crypto_context cryptoctx,
2277                   pkinit_identity_crypto_context id_cryptoctx,
2278                   unsigned char *subjectPublicKey_data,
2279                   unsigned int subjectPublicKey_length,
2280                   unsigned char **client_key,
2281                   unsigned int *client_key_len)
2282 {
2283     /* Solaris Kerberos */
2284     krb5_error_code retval = KRB5_PREAUTH_FAILED;
2285     BIGNUM *server_pub_key = NULL;
2286     ASN1_INTEGER *pub_key = NULL;
2287     const unsigned char *p = NULL;


2335         ASN1_INTEGER_free(pub_key);
2336     if (data != NULL)
2337         free (data);
2338 
2339     return retval;
2340 }
2341 
2342 /* ARGSUSED */
2343 krb5_error_code
2344 server_check_dh(krb5_context context,
2345                 pkinit_plg_crypto_context cryptoctx,
2346                 pkinit_req_crypto_context req_cryptoctx,
2347                 pkinit_identity_crypto_context id_cryptoctx,
2348                 krb5_octet_data *dh_params,
2349                 int minbits)
2350 {
2351     DH *dh = NULL;
2352     unsigned char *tmp = NULL;
2353     int dh_prime_bits;
2354     krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;

2355 
2356     tmp = dh_params->data;
2357     dh = DH_new();
2358     dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
2359     if (dh == NULL) {
2360         pkiDebug("failed to decode dhparams\n");
2361         goto cleanup;
2362     }
2363 


2364     /* KDC SHOULD check to see if the key parameters satisfy its policy */
2365     dh_prime_bits = BN_num_bits(dh->p);
2366     if (minbits && dh_prime_bits < minbits) {
2367         pkiDebug("client sent dh params with %d bits, we require %d\n",
2368                  dh_prime_bits, minbits);
2369         goto cleanup;
2370     }
2371 
2372     /* check dhparams is group 2 */
2373     if (pkinit_check_dh_params(cryptoctx->dh_1024->p,
2374                                dh->p, dh->g, dh->q) == 0) {
2375         retval = 0;
2376         goto cleanup;
2377     }
2378 
2379     /* check dhparams is group 14 */
2380     if (pkinit_check_dh_params(cryptoctx->dh_2048->p,
2381                                dh->p, dh->g, dh->q) == 0) {
2382         retval = 0;
2383         goto cleanup;
2384     }
2385 
2386     /* check dhparams is group 16 */
2387     if (pkinit_check_dh_params(cryptoctx->dh_4096->p,
2388                                dh->p, dh->g, dh->q) == 0) {
2389         retval = 0;
2390         goto cleanup;
2391     }
2392 
2393   cleanup:
2394     if (retval == 0)
2395         req_cryptoctx->dh = dh;
2396     else
2397         DH_free(dh);
2398 
2399     return retval;
2400 }
2401 
2402 /* kdc's dh function */
2403 /* ARGSUSED */
2404 krb5_error_code
2405 server_process_dh(krb5_context context,
2406                   pkinit_plg_crypto_context plg_cryptoctx,
2407                   pkinit_req_crypto_context cryptoctx,
2408                   pkinit_identity_crypto_context id_cryptoctx,
2409                   unsigned char *data,
2410                   unsigned int data_len,
2411                   unsigned char **dh_pubkey,
2412                   unsigned int *dh_pubkey_len,
2413                   unsigned char **server_key,
2414                   unsigned int *server_key_len)
2415 {
2416     /* Solaris Kerberos */
2417     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2418     DH *dh = NULL, *dh_server = NULL;
2419     unsigned char *p = NULL;
2420     ASN1_INTEGER *pub_key = NULL;


2421 
2422     /* get client's received DH parameters that we saved in server_check_dh */
2423     dh = cryptoctx->dh;
2424 
2425     dh_server = DH_new();
2426     if (dh_server == NULL)
2427         goto cleanup;
2428     dh_server->p = BN_dup(dh->p);
2429     dh_server->g = BN_dup(dh->g);
2430     dh_server->q = BN_dup(dh->q);
2431 
2432     /* decode client's public key */
2433     p = data;
2434     pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len);




2435     if (pub_key == NULL)
2436         goto cleanup;
2437     dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL);
2438     if (dh->pub_key == NULL)
2439         goto cleanup;
2440     ASN1_INTEGER_free(pub_key);
2441 
2442     if (!DH_generate_key(dh_server))
2443         goto cleanup;
2444 
2445     /* generate DH session key */
2446     *server_key_len = DH_size(dh_server);
2447     if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL)

2448         goto cleanup;
2449     DH_compute_key(*server_key, dh->pub_key, dh_server);

2450 
2451 #ifdef DEBUG_DH
2452     print_dh(dh_server, "client&server's DH params\n");
2453     print_pubkey(dh->pub_key, "client's pub_key=");
2454     print_pubkey(dh_server->pub_key, "server's pub_key=");
2455     pkiDebug("server secret key=");
2456     print_buffer(*server_key, *server_key_len);
2457 #endif
2458 
2459     /* KDC reply */
2460     /* pack DH public key */
2461     /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2462      * encoding shall be used as the contents (the value) of the
2463      * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2464      * data element
2465      */
2466     if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL)
2467         goto cleanup;
2468     *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
2469     if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL)

2470         goto cleanup;
2471     i2d_ASN1_INTEGER(pub_key, &p);
2472     if (pub_key != NULL)
2473         ASN1_INTEGER_free(pub_key);
2474 
2475     retval = 0;
2476 
2477     if (dh_server != NULL)
2478         DH_free(dh_server);
2479     return retval;
2480 
2481   cleanup:
2482     if (dh_server != NULL)
2483         DH_free(dh_server);
2484     if (*dh_pubkey != NULL)
2485         free(*dh_pubkey);
2486     if (*server_key != NULL)
2487         free(*server_key);
2488 
2489     return retval;
2490 }
2491 
2492 /*
2493  * Solaris Kerberos:
2494  * Add locking around did_init to make it MT-safe.
2495  */
2496 static krb5_error_code
2497 openssl_init()
2498 {
2499     krb5_error_code ret = 0;
2500     static int did_init = 0;
2501     static k5_mutex_t init_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
2502 
2503     ret = k5_mutex_lock(&init_mutex);
2504     if (ret == 0) {
2505         if (!did_init) {
2506             /* initialize openssl routines */





2507             CRYPTO_malloc_init();
2508             ERR_load_crypto_strings();
2509             OpenSSL_add_all_algorithms();

2510             did_init++;
2511         }
2512         k5_mutex_unlock(&init_mutex);
2513     }
2514     return (ret);
2515 }
2516 
2517 static krb5_error_code
2518 pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q,
2519                         unsigned char **buf, unsigned int *buf_len)
2520 {
2521     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2522     int bufsize = 0, r = 0;
2523     unsigned char *tmp = NULL;
2524     ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
2525 
2526     if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL)
2527         goto cleanup;
2528     if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL)
2529         goto cleanup;
2530     if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL)
2531         goto cleanup;
2532     bufsize = i2d_ASN1_INTEGER(ap, NULL);
2533     bufsize += i2d_ASN1_INTEGER(ag, NULL);
2534     bufsize += i2d_ASN1_INTEGER(aq, NULL);
2535 
2536     r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
2537 
2538     tmp = *buf = (unsigned char *)malloc((size_t) r);


2543 
2544     i2d_ASN1_INTEGER(ap, &tmp);
2545     i2d_ASN1_INTEGER(ag, &tmp);
2546     i2d_ASN1_INTEGER(aq, &tmp);
2547 
2548     *buf_len = r;
2549 
2550     retval = 0;
2551 
2552 cleanup:
2553     if (ap != NULL)
2554         ASN1_INTEGER_free(ap);
2555     if (ag != NULL)
2556         ASN1_INTEGER_free(ag);
2557     if (aq != NULL)
2558         ASN1_INTEGER_free(aq);
2559 
2560     return retval;
2561 }
2562 


2563 static DH *
2564 pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
2565 {
2566     ASN1_INTEGER ai, *aip = NULL;
2567     long length = (long) len;
2568 
2569     M_ASN1_D2I_vars(a, DH *, DH_new);
2570 
2571     M_ASN1_D2I_Init();
2572     M_ASN1_D2I_start_sequence();
2573     aip = &ai;
2574     ai.data = NULL;
2575     ai.length = 0;
2576     M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2577     if (aip == NULL)
2578         return NULL;
2579     else {
2580         (*a)->p = ASN1_INTEGER_to_BN(aip, NULL);
2581         if ((*a)->p == NULL)
2582             return NULL;


2602     }
2603     M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2604     if (aip == NULL)
2605         return NULL;
2606     else {
2607         (*a)->q = ASN1_INTEGER_to_BN(aip, NULL);
2608         if ((*a)->q == NULL)
2609             return NULL;
2610         if (ai.data != NULL) {
2611             OPENSSL_free(ai.data);
2612             ai.data = NULL;
2613             ai.length = 0;
2614         }
2615 
2616     }
2617     M_ASN1_D2I_end_sequence();
2618     M_ASN1_D2I_Finish(a, DH_free, 0);
2619 
2620 }
2621 

























































2622 static krb5_error_code
2623 pkinit_create_sequence_of_principal_identifiers(
2624     krb5_context context,
2625     pkinit_plg_crypto_context plg_cryptoctx,
2626     pkinit_req_crypto_context req_cryptoctx,
2627     pkinit_identity_crypto_context id_cryptoctx,
2628     int type,
2629     krb5_data **out_data)
2630 {
2631     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2632     krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
2633     krb5_data *td_certifiers = NULL, *data = NULL;
2634     krb5_typed_data **typed_data = NULL;
2635 
2636     switch(type) {
2637         case TD_TRUSTED_CERTIFIERS:
2638             retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
2639                 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
2640             if (retval) {
2641                 pkiDebug("create_krb5_trustedCertifiers failed\n");


2746 
2747     return retval;
2748 }
2749 
2750 /* ARGSUSED */
2751 krb5_error_code
2752 pkinit_create_td_dh_parameters(krb5_context context,
2753                                pkinit_plg_crypto_context plg_cryptoctx,
2754                                pkinit_req_crypto_context req_cryptoctx,
2755                                pkinit_identity_crypto_context id_cryptoctx,
2756                                pkinit_plg_opts *opts,
2757                                krb5_data **out_data)
2758 {
2759     /* Solaris Kerberos */
2760     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2761     unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
2762     unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
2763     krb5_typed_data **typed_data = NULL;
2764     krb5_data *data = NULL, *encoded_algId = NULL;
2765     krb5_algorithm_identifier **algId = NULL;

2766 
2767     /* Solaris Kerberos */
2768     if (opts->dh_min_bits > 4096) {
2769         retval = EINVAL;
2770         goto cleanup;
2771     }
2772 
2773     if (opts->dh_min_bits <= 1024) {
2774         retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p,
2775             plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q,
2776             &buf1, &buf1_len);
2777         if (retval)
2778             goto cleanup;
2779     }
2780     if (opts->dh_min_bits <= 2048) {
2781         retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p,
2782             plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q,
2783             &buf2, &buf2_len);
2784         if (retval)
2785             goto cleanup;
2786     }
2787     retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p,
2788         plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q,
2789         &buf3, &buf3_len);
2790     if (retval)
2791         goto cleanup;
2792 
2793     if (opts->dh_min_bits <= 1024) {
2794         algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
2795         if (algId == NULL)
2796             goto cleanup;
2797         algId[3] = NULL;
2798         algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2799         if (algId[0] == NULL)
2800             goto cleanup;
2801         algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
2802         if (algId[0]->parameters.data == NULL)
2803             goto cleanup;
2804         (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
2805         algId[0]->parameters.length = buf2_len;
2806         algId[0]->algorithm = dh_oid;
2807 
2808         algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
2809         if (algId[1] == NULL)


2963     if (is == NULL)
2964         goto cleanup;
2965 
2966     status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
2967     if (!status) {
2968         status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
2969         if (!status)
2970             *valid_kdcPkId = 1;
2971     }
2972 
2973     retval = 0;
2974 cleanup:
2975     X509_NAME_free(is->issuer);
2976     ASN1_INTEGER_free(is->serial);
2977     free(is);
2978 
2979     return retval;
2980 }
2981 
2982 static int
2983 pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1)

2984 {
2985     BIGNUM *g2 = NULL, *q2 = NULL;
2986     /* Solaris Kerberos */
2987     int retval = EINVAL;
2988 
2989     if (!BN_cmp(p1, p2)) {
2990         g2 = BN_new();
2991         BN_set_word(g2, DH_GENERATOR_2);
2992         if (!BN_cmp(g1, g2)) {
2993             q2 = BN_new();
2994             BN_rshift1(q2, p1);
2995             if (!BN_cmp(q1, q2)) {
2996                 pkiDebug("good %d dhparams\n", BN_num_bits(p1));
2997                 retval = 0;
2998             } else
2999                 pkiDebug("bad group 2 q dhparameter\n");
3000             BN_free(q2);
3001         } else
3002             pkiDebug("bad g dhparameter\n");
3003         BN_free(g2);


3007     return retval;
3008 }
3009 
3010 /* ARGSUSED */
3011 krb5_error_code
3012 pkinit_process_td_dh_params(krb5_context context,
3013                             pkinit_plg_crypto_context cryptoctx,
3014                             pkinit_req_crypto_context req_cryptoctx,
3015                             pkinit_identity_crypto_context id_cryptoctx,
3016                             krb5_algorithm_identifier **algId,
3017                             int *new_dh_size)
3018 {
3019     krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3020     int i = 0, use_sent_dh = 0, ok = 0;
3021 
3022     pkiDebug("dh parameters\n");
3023 
3024     while (algId[i] != NULL) {
3025         DH *dh = NULL;
3026         unsigned char *tmp = NULL;

3027         int dh_prime_bits = 0;
3028 
3029         if (algId[i]->algorithm.length != dh_oid.length ||
3030             memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
3031             goto cleanup;
3032 
3033         tmp = algId[i]->parameters.data;
3034         dh = DH_new();
3035         dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
3036         dh_prime_bits = BN_num_bits(dh->p);
3037         pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
3038                  *new_dh_size, dh_prime_bits);

3039         switch(dh_prime_bits) {
3040             case 1024:
3041                 if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p,
3042                         dh->g, dh->q) == 0) {
3043                     *new_dh_size = 1024;
3044                     ok = 1;
3045                 }
3046                 break;
3047             case 2048:
3048                 if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p,
3049                         dh->g, dh->q) == 0) {
3050                     *new_dh_size = 2048;
3051                     ok = 1;
3052                 }
3053                 break;
3054             case 4096:
3055                 if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p,
3056                         dh->g, dh->q) == 0) {
3057                     *new_dh_size = 4096;
3058                     ok = 1;
3059                 }
3060                 break;
3061             default:
3062                 break;
3063         }
3064         if (!ok) {
3065             DH_check(dh, &retval);
3066             if (retval != 0) {
3067                 pkiDebug("DH parameters provided by server are unacceptable\n");
3068                 retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3069             }
3070             else {
3071                 use_sent_dh = 1;
3072                 ok = 1;
3073             }
3074         }
3075         if (!use_sent_dh)
3076             DH_free(dh);


3096 /* ARGSUSED */ 
3097 static int
3098 openssl_callback(int ok, X509_STORE_CTX * ctx)
3099 {
3100 #ifdef DEBUG
3101     if (!ok) {
3102         char buf[DN_BUF_LEN];
3103 
3104         X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
3105         pkiDebug("cert = %s\n", buf);
3106         pkiDebug("callback function: %d (%s)\n", ctx->error,
3107                 X509_verify_cert_error_string(ctx->error));
3108     }
3109 #endif
3110     return ok;
3111 }
3112 
3113 static int
3114 openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
3115 {
3116     if (!ok) {
3117         switch (ctx->error) {
3118             case X509_V_ERR_UNABLE_TO_GET_CRL:
3119                 return 1;
3120             default:
3121                 return 0;
3122         }
3123     }
3124     return ok;
3125 }
3126 
3127 static ASN1_OBJECT *
3128 pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
3129 {
3130     int nid;
3131 
3132     switch (pkcs7_type) {
3133         case CMS_SIGN_CLIENT:
3134             return cryptoctx->id_pkinit_authData;
3135         case CMS_SIGN_DRAFT9:
3136             /*
3137              * Delay creating this OID until we know we need it.
3138              * It shadows an existing OpenSSL oid.  If it
3139              * is created too early, it breaks things like
3140              * the use of pkcs12 (which uses pkcs7 structures).
3141              * We need this shadow version because our code
3142              * depends on the "other" type to be unknown to the
3143              * OpenSSL code.


3292     ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
3293                     V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3294 
3295     i2d_ASN1_OBJECT(oid, &p);
3296 
3297     ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
3298     (void) memcpy(p, data, data_len);
3299 
3300     *out_len = tot_len;
3301 
3302     return 0;
3303 }
3304 #endif
3305 
3306 static int
3307 prepare_enc_data(unsigned char *indata,
3308                  int indata_len,
3309                  unsigned char **outdata,
3310                  int *outdata_len)
3311 {
3312     /* Solaris Kerberos */
3313     ASN1_const_CTX c;
3314     long length = indata_len;
3315     int Ttag, Tclass;
3316     long Tlen;
3317 
3318     c.pp = (const unsigned char **)&indata;
3319     c.q = *(const unsigned char **)&indata;
3320     c.error = ERR_R_NESTED_ASN1_ERROR;
3321     c.p= *(const unsigned char **)&indata;
3322     c.max = (length == 0)?0:(c.p+length);
3323 
3324     asn1_GetSequence(&c,&length);




3325 
3326     ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
3327     c.p += Tlen;
3328     ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
3329 
3330     asn1_const_Finish(&c);
3331 
3332     *outdata = (unsigned char *)malloc((size_t)Tlen);
3333     /* Solaris Kerberos */
3334     if (outdata == NULL)
3335         return ENOMEM;


3336     
3337     (void) memcpy(*outdata, c.p, (size_t)Tlen);
3338     *outdata_len = Tlen;
3339 
3340     return 0;
3341 }
3342 
3343 #ifndef WITHOUT_PKCS11
3344 static void *
3345 pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
3346 {
3347     void *handle;
3348     CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
3349 
3350     pkiDebug("loading module \"%s\"... ", modname);
3351     /* Solaris Kerberos */
3352     handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
3353     if (handle == NULL) {
3354         pkiDebug("not found\n");
3355         return NULL;
3356     }
3357     getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
3358     if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
3359         (void) dlclose(handle);


4351  * You must call pkinit_get_certs before calling pkinit_find_private_key
4352  * (that's because we need the ID of the private key)
4353  *
4354  * pkcs11 says the id of the key doesn't have to match that of the cert, but
4355  * I can't figure out any other way to decide which key to use.
4356  *
4357  * We should only find one key that fits all the requirements.
4358  * If there are more than one, we just take the first one.
4359  */
4360 
4361 /* ARGSUSED */
4362 krb5_error_code
4363 pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
4364                         CK_ATTRIBUTE_TYPE usage,
4365                         CK_OBJECT_HANDLE *objp)
4366 {
4367     CK_OBJECT_CLASS cls;
4368     CK_ATTRIBUTE attrs[4];
4369     CK_ULONG count;
4370     CK_KEY_TYPE keytype;

4371     unsigned int nattrs = 0;
4372     int r;
4373 #ifdef PKINIT_USE_KEY_USAGE
4374     CK_BBOOL true_false;
4375 #endif
4376 
4377     cls = CKO_PRIVATE_KEY;
4378     attrs[nattrs].type = CKA_CLASS;
4379     attrs[nattrs].pValue = &cls;
4380     attrs[nattrs].ulValueLen = sizeof cls;
4381     nattrs++;
4382 
4383 #ifdef PKINIT_USE_KEY_USAGE
4384     /*
4385      * Some cards get confused if you try to specify a key usage,
4386      * so don't, and hope for the best. This will fail if you have
4387      * several keys with the same id and different usages but I have
4388      * not seen this on real cards.
4389      */
4390     true_false = TRUE;


4411                  pkinit_pkcs11_code_to_text(r));
4412         return KRB5KDC_ERR_PREAUTH_FAILED;
4413     }
4414 
4415     r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4416     id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
4417     pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
4418 
4419     /*
4420      * Solaris Kerberos:
4421      * The CKA_ID may not be correctly set for the private key. For e.g. when
4422      * storing a private key in softtoken pktool(1) doesn't generate or store
4423      * a CKA_ID for the private key. Another way to identify the private key is
4424      * to look for a private key with the same RSA modulus as the public key
4425      * in the certificate.
4426      */
4427     if (r == CKR_OK && count != 1) {
4428 
4429         EVP_PKEY *priv;
4430         X509 *cert;

4431         unsigned int n_len;
4432         unsigned char *n_bytes;
4433 
4434         cert = sk_X509_value(id_cryptoctx->my_certs, 0);
4435         priv = X509_get_pubkey(cert);
4436         if (priv == NULL) {
4437                 pkiDebug("Failed to extract pub key from cert\n");
4438                 return KRB5KDC_ERR_PREAUTH_FAILED;
4439         }
4440 
4441         nattrs = 0;
4442         cls = CKO_PRIVATE_KEY;
4443         attrs[nattrs].type = CKA_CLASS;
4444         attrs[nattrs].pValue = &cls;
4445         attrs[nattrs].ulValueLen = sizeof cls;
4446         nattrs++;
4447 
4448 #ifdef PKINIT_USE_KEY_USAGE
4449         true_false = TRUE;
4450         attrs[nattrs].type = usage;
4451         attrs[nattrs].pValue = &true_false;
4452         attrs[nattrs].ulValueLen = sizeof true_false;
4453         nattrs++;
4454 #endif
4455 
4456         keytype = CKK_RSA;
4457         attrs[nattrs].type = CKA_KEY_TYPE;
4458         attrs[nattrs].pValue = &keytype;
4459         attrs[nattrs].ulValueLen = sizeof keytype;
4460         nattrs++;
4461 
4462         n_len = BN_num_bytes(priv->pkey.rsa->n);








4463         n_bytes = (unsigned char *) malloc((size_t) n_len);
4464         if (n_bytes == NULL) {
4465                 return (ENOMEM);
4466         }
4467 
4468         if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) {
4469                 free (n_bytes);
4470                 pkiDebug("zero-byte key modulus\n");
4471                 return KRB5KDC_ERR_PREAUTH_FAILED;
4472         }
4473 
4474         attrs[nattrs].type = CKA_MODULUS;
4475         attrs[nattrs].ulValueLen = n_len; 
4476         attrs[nattrs].pValue = n_bytes;
4477 
4478         nattrs++;
4479 
4480         r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
4481         free (n_bytes);
4482         if (r != CKR_OK) {
4483                 pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
4484                         pkinit_pkcs11_code_to_text(r));
4485                 return KRB5KDC_ERR_PREAUTH_FAILED;
4486         }
4487 
4488         r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);


4757     /* Solaris Kerberos */
4758     int len;
4759     unsigned char *buf = NULL;
4760     int buf_len = 0;
4761 
4762     /* Solaris Kerberos */
4763     if (out_data == NULL || out_data_len == NULL)
4764         return EINVAL;
4765 
4766     if (cert && !X509_check_private_key(cert, pkey)) {
4767         pkiDebug("private key does not match certificate\n");
4768         /* Solaris Kerberos */
4769         return EINVAL;
4770     }
4771 
4772     buf_len = EVP_PKEY_size(pkey);
4773     buf = (unsigned char *)malloc((size_t) buf_len + 10);
4774     if (buf == NULL)
4775         return ENOMEM;
4776 
4777 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4778     len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
4779 #else
4780     len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
4781 #endif
4782     if (len <= 0) {
4783         pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
4784         /* Solaris Kerberos */
4785         free(buf);
4786         return KRB5KRB_ERR_GENERIC;
4787     }
4788     *out_data = buf;
4789     *out_data_len = len;
4790 
4791     return 0;
4792 }
4793 
4794 static krb5_error_code
4795 create_signature(unsigned char **sig, unsigned int *sig_len,
4796                  unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
4797 {
4798     krb5_error_code retval = ENOMEM;
4799     EVP_MD_CTX md_ctx;
4800 
4801     if (pkey == NULL)
4802         /* Solaris Kerberos */
4803         return EINVAL;
4804 
4805     EVP_VerifyInit(&md_ctx, EVP_sha1());
4806     EVP_SignUpdate(&md_ctx, data, data_len);



4807     *sig_len = EVP_PKEY_size(pkey);
4808     if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
4809         goto cleanup;
4810     EVP_SignFinal(&md_ctx, *sig, sig_len, pkey);
4811 
4812     retval = 0;
4813 
4814   cleanup:
4815     EVP_MD_CTX_cleanup(&md_ctx);
4816 
4817     return retval;
4818 }
4819 
4820 /*
4821  * Note:
4822  * This is not the routine the KDC uses to get its certificate.
4823  * This routine is intended to be called by the client
4824  * to obtain the KDC's certificate from some local storage
4825  * to be sent as a hint in its request to the KDC.
4826  */
4827 /* ARGSUSED */
4828 krb5_error_code
4829 pkinit_get_kdc_cert(krb5_context context,
4830                     pkinit_plg_crypto_context plg_cryptoctx,
4831                     pkinit_req_crypto_context req_cryptoctx,
4832                     pkinit_identity_crypto_context id_cryptoctx,
4833                     krb5_principal princ)
4834 {
4835    /* Solaris Kerberos */


6081         krb5_cas[i]->subjectName.length = 0;
6082         krb5_cas[i]->subjectName.data = NULL;
6083 
6084         xn = X509_get_subject_name(x);
6085         len = i2d_X509_NAME(xn, NULL);
6086         if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
6087             goto cleanup;
6088         i2d_X509_NAME(xn, &p);
6089         krb5_cas[i]->subjectName.length = len;
6090 
6091         /* fill-in issuerAndSerialNumber */
6092         krb5_cas[i]->issuerAndSerialNumber.length = 0;
6093         krb5_cas[i]->issuerAndSerialNumber.magic = 0;
6094         krb5_cas[i]->issuerAndSerialNumber.data = NULL;
6095 
6096 #ifdef LONGHORN_BETA_COMPAT
6097 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6098 #endif
6099         is = PKCS7_ISSUER_AND_SERIAL_new();
6100         X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6101         M_ASN1_INTEGER_free(is->serial);
6102         is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
6103         len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6104         if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
6105              (unsigned char *)malloc((size_t) len)) == NULL)
6106             goto cleanup;
6107         i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6108         krb5_cas[i]->issuerAndSerialNumber.length = len;
6109 #ifdef LONGHORN_BETA_COMPAT
6110 }
6111 #endif
6112 
6113         /* fill-in subjectKeyIdentifier */
6114         krb5_cas[i]->subjectKeyIdentifier.length = 0;
6115         krb5_cas[i]->subjectKeyIdentifier.magic = 0;
6116         krb5_cas[i]->subjectKeyIdentifier.data = NULL;
6117 
6118 
6119 #ifdef LONGHORN_BETA_COMPAT
6120 if (longhorn == 0) {    /* XXX Longhorn doesn't like this */
6121 #endif
6122         if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {


6286                 krb5_cas[i]->choice = choice_trusted_cas_principalName;
6287                 break;
6288             case choice_trusted_cas_caName:
6289                 krb5_cas[i]->choice = choice_trusted_cas_caName;
6290                 krb5_cas[i]->u.caName.data = NULL;
6291                 krb5_cas[i]->u.caName.length = 0;
6292                 xn = X509_get_subject_name(x);
6293                 len = i2d_X509_NAME(xn, NULL);
6294                 if ((p = krb5_cas[i]->u.caName.data =
6295                     (unsigned char *)malloc((size_t) len)) == NULL)
6296                     goto cleanup;
6297                 i2d_X509_NAME(xn, &p);
6298                 krb5_cas[i]->u.caName.length = len;
6299                 break;
6300             case choice_trusted_cas_issuerAndSerial:
6301                 krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
6302                 krb5_cas[i]->u.issuerAndSerial.data = NULL;
6303                 krb5_cas[i]->u.issuerAndSerial.length = 0;
6304                 is = PKCS7_ISSUER_AND_SERIAL_new();
6305                 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6306                 M_ASN1_INTEGER_free(is->serial);
6307                 is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
6308                 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6309                 if ((p = krb5_cas[i]->u.issuerAndSerial.data =
6310                     (unsigned char *)malloc((size_t) len)) == NULL)
6311                     goto cleanup;
6312                 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6313                 krb5_cas[i]->u.issuerAndSerial.length = len;
6314                 if (is != NULL) {
6315                     if (is->issuer != NULL)
6316                         X509_NAME_free(is->issuer);
6317                     if (is->serial != NULL)
6318                         ASN1_INTEGER_free(is->serial);
6319                     free(is);
6320                 }
6321                 break;
6322             default: break;
6323         }
6324     }
6325     retval = 0;
6326     *ids = krb5_cas;
6327 cleanup:


6336 create_issuerAndSerial(krb5_context context,
6337                        pkinit_plg_crypto_context plg_cryptoctx,
6338                        pkinit_req_crypto_context req_cryptoctx,
6339                        pkinit_identity_crypto_context id_cryptoctx,
6340                        unsigned char **out,
6341                        unsigned int *out_len)
6342 {
6343     unsigned char *p = NULL;
6344     PKCS7_ISSUER_AND_SERIAL *is = NULL;
6345     int len = 0;
6346     krb5_error_code retval = ENOMEM;
6347     X509 *cert = req_cryptoctx->received_cert;
6348 
6349     *out = NULL;
6350     *out_len = 0;
6351     if (req_cryptoctx->received_cert == NULL)
6352         return 0;
6353 
6354     is = PKCS7_ISSUER_AND_SERIAL_new();
6355     X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
6356     M_ASN1_INTEGER_free(is->serial);
6357     is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
6358     len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6359     if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
6360         goto cleanup;
6361     i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6362     *out_len = len;
6363     retval = 0;
6364 
6365 cleanup:
6366     X509_NAME_free(is->issuer);
6367     ASN1_INTEGER_free(is->serial);
6368     free(is);
6369 
6370     return retval;
6371 }
6372 
6373 static int
6374 pkcs7_decrypt(krb5_context context,
6375               pkinit_identity_crypto_context id_cryptoctx,
6376               PKCS7 *p7,
6377               BIO *data)


6522     xalg=p7->d.enveloped->enc_data->algorithm;
6523 #endif
6524 
6525     if ((etmp=BIO_new(BIO_f_cipher())) == NULL) {
6526         PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
6527         goto cleanup;
6528     }
6529 
6530     /* It was encrypted, we need to decrypt the secret key
6531      * with the private key */
6532 
6533     /* Find the recipientInfo which matches the passed certificate
6534      * (if any)
6535      */
6536 
6537     if (cert) {
6538         for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6539             int tmp_ret = 0;
6540             ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6541             tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
6542                                     cert->cert_info->issuer);
6543             if (!tmp_ret) {
6544                 tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber,
6545                                              ri->issuer_and_serial->serial);
6546                 if (!tmp_ret)
6547                     break;
6548             }
6549             ri=NULL;
6550         }
6551         if (ri == NULL) {
6552             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6553                      PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6554             goto cleanup;
6555         }
6556         
6557     }
6558 
6559     /* If we haven't got a certificate try each ri in turn */
6560 
6561     if (cert == NULL) {
6562         for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6563             ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6564             jj = pkinit_decode_data(context, id_cryptoctx,
6565                 M_ASN1_STRING_data(ri->enc_key),
6566                 (unsigned int) M_ASN1_STRING_length(ri->enc_key),
6567                 &tmp, &tmp_len);
6568             if (jj) {
6569                 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6570                 goto cleanup;
6571             }
6572 
6573             if (!jj && tmp_len > 0) {
6574                 jj = tmp_len;
6575                 break;
6576             }
6577 
6578             ERR_clear_error();
6579             ri = NULL;
6580         }
6581 
6582         if (ri == NULL) {
6583             PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
6584             goto cleanup;
6585         }
6586     }
6587     else {
6588         jj = pkinit_decode_data(context, id_cryptoctx,
6589             M_ASN1_STRING_data(ri->enc_key),
6590             (unsigned int) M_ASN1_STRING_length(ri->enc_key),
6591             &tmp, &tmp_len);
6592         /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
6593         if (jj || tmp_len == 0) {
6594             PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6595             goto cleanup;
6596         }
6597         jj = tmp_len;
6598     }
6599 
6600     evp_ctx=NULL;
6601     BIO_get_cipher_ctx(etmp,&evp_ctx);
6602     if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
6603         goto cleanup;
6604     if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
6605         goto cleanup;
6606 
6607     if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
6608         /* Some S/MIME clients don't use the same key
6609          * and effective key length. The key length is
6610          * determined by the size of the decrypted RSA key.
6611          */
6612         if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
6613             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6614                      PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
6615             goto cleanup;
6616         }
6617     }
6618     if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
6619         goto cleanup;
6620 
6621     OPENSSL_cleanse(tmp,jj);
6622 
6623     if (out == NULL)
6624         out=etmp;
6625     else
6626         BIO_push(out,etmp);
6627     etmp=NULL;
6628 
6629     if (data_body->length > 0)
6630         bio = BIO_new_mem_buf(data_body->data, data_body->length);
6631     else {
6632         bio=BIO_new(BIO_s_mem());
6633         BIO_set_mem_eof_return(bio,0);
6634     }




  14  * portion of this software, then the disclaimer below must
  15  * also be included.
  16  *
  17  * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
  18  * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
  19  * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
  20  * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
  21  * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
  22  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
  23  * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
  24  * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
  25  * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
  26  * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
  27  * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
  28  * SUCH DAMAGES.
  29  */
  30 
  31 /*
  32  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  33  * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
  34  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  35  */
  36 
  37 #include <errno.h>
  38 #include <string.h>
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #include <dlfcn.h>
  42 #include <unistd.h>
  43 #include <dirent.h>
  44 
  45 
  46 /* Solaris Kerberos */
  47 #include <libintl.h>
  48 #include <assert.h>
  49 #include <security/pam_appl.h>
  50 #include <ctype.h>
  51 #include "k5-int.h"
  52 #include <ctype.h>
  53 
  54 /*


 353     0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
 354     0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
 355     0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
 356     0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
 357     0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
 358     0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
 359     0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
 360     0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
 361     0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
 362     0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
 363     0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
 364     0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
 365     0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
 366     0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
 367     0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
 368     0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
 369     0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
 370     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 371 };
 372 
 373 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 374 /*
 375  * Many things have changed in OpenSSL 1.1. The code in this file has been
 376  * updated to use the v1.1 APIs but some are new and require emulation
 377  * for older OpenSSL versions.
 378  */
 379 
 380 /* EVP_MD_CTX construct and destructor names have changed */
 381 
 382 #define EVP_MD_CTX_new EVP_MD_CTX_create
 383 #define EVP_MD_CTX_free EVP_MD_CTX_destroy
 384 
 385 /* ASN1_STRING_data is deprecated */
 386 #define ASN1_STRING_get0_data ASN1_STRING_data
 387 
 388 /* X509_STORE_CTX_trusted_stack is deprecated */
 389 #define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
 390 
 391 /* get_rfc2409_prime_1024() has been renamed. */
 392 #define BN_get_rfc2409_prime_1024 get_rfc2409_prime_1024
 393 
 394 #define OBJ_get0_data(o) ((o)->data)
 395 #define OBJ_length(o) ((o)->length)
 396 
 397 /* Some new DH functions that aren't in OpenSSL 1.0.x */
 398 #define DH_bits(dh) BN_num_bits((dh)->p);
 399 
 400 #define DH_set0_pqg(dh, p, q, g) __DH_set0_pqg(dh, p, q, g)
 401 static int
 402 __DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
 403 {
 404     if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL))
 405         return 0;
 406 
 407     if (p != NULL) {
 408         BN_free(dh->p);
 409         dh->p = p;
 410     }
 411     if (q != NULL) {
 412         BN_free(dh->q);
 413         dh->q = q;
 414     }
 415     if (g != NULL) {
 416         BN_free(dh->g);
 417         dh->g = g;
 418     }
 419 
 420     if (q != NULL) {
 421         dh->length = BN_num_bits(q);
 422     }
 423 
 424     return 1;
 425 }
 426 
 427 #define DH_get0_pqg(dh, p, q, g) __DH_get0_pqg(dh, p, q, g)
 428 static void
 429 __DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q,
 430     const BIGNUM **g)
 431 {
 432     if (p != NULL)
 433         *p = dh->p;
 434     if (q != NULL)
 435         *q = dh->q;
 436     if (g != NULL)
 437         *g = dh->g;
 438 }
 439 
 440 #define DH_set0_key(dh, pub, priv) __DH_set0_key(dh, pub, priv)
 441 static int
 442 __DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
 443 {
 444     if (pub_key != NULL) {
 445         BN_free(dh->pub_key);
 446         dh->pub_key = pub_key;
 447     }
 448     if (priv_key != NULL) {
 449         BN_free(dh->priv_key);
 450         dh->priv_key = priv_key;
 451     }
 452 
 453     return 1;
 454 }
 455 
 456 #define DH_get0_key(dh, pub, priv) __DH_get0_key(dh, pub, priv)
 457 static void
 458 __DH_get0_key(const DH *dh, const BIGNUM **pub, const BIGNUM **priv)
 459 {
 460     if (pub != NULL)
 461         *pub = dh->pub_key;
 462     if (priv != NULL)
 463         *priv = dh->priv_key;
 464 }
 465 
 466 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
 467 
 468 /* Solaris Kerberos */
 469 static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
 470 static int pkinit_oids_refs = 0;
 471 
 472 krb5_error_code
 473 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
 474 
 475     krb5_error_code retval = ENOMEM;
 476     pkinit_plg_crypto_context ctx = NULL;
 477 
 478     /* initialize openssl routines */
 479     /* Solaris Kerberos */
 480     retval = openssl_init();
 481     if (retval != 0)
 482         goto out;
 483 
 484     ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
 485     if (ctx == NULL)
 486         goto out;
 487     (void) memset(ctx, 0, sizeof(*ctx));


 735         pkiDebug("failed to read private key from %s\n", filename);
 736         goto cleanup;
 737     }
 738     *retkey = pkey;
 739     retval = 0;
 740 cleanup:
 741     if (tmp != NULL)
 742         BIO_free(tmp);
 743     return retval;
 744 }
 745 
 746 static void
 747 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
 748 {
 749     if (ctx == NULL)
 750         return;
 751 
 752     /* Only call OBJ_cleanup once! */
 753     /* Solaris Kerberos: locking */
 754     k5_mutex_lock(&oids_mutex);
 755 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 756     /*
 757      * In OpenSSL versions prior to 1.1.0, OBJ_cleanup() cleaned up OpenSSL's
 758      * internal object table. This function is deprecated in version 1.1.0.
 759      * No explicit de-initialisation is now required.
 760      */
 761     if (--pkinit_oids_refs == 0)
 762         OBJ_cleanup();
 763 #else
 764     pkinit_oids_refs--;
 765 #endif
 766     k5_mutex_unlock(&oids_mutex);
 767 }
 768 
 769 /* Construct an OpenSSL DH object for an Oakley group. */
 770 static DH *
 771 make_dhprime(uint8_t *prime, size_t len)
 772 {
 773     DH *dh = NULL;
 774     BIGNUM *p = NULL, *q = NULL, *g = NULL;
 775 
 776     if ((p = BN_bin2bn(prime, len, NULL)) == NULL)
 777         goto cleanup;
 778     if ((q = BN_new()) == NULL)
 779         goto cleanup;
 780     if (!BN_rshift1(q, p))
 781         goto cleanup;
 782     if ((g = BN_new()) == NULL)
 783         goto cleanup;
 784     if (!BN_set_word(g, DH_GENERATOR_2))
 785         goto cleanup;
 786 
 787     dh = DH_new();
 788     if (dh == NULL)
 789         goto cleanup;
 790     DH_set0_pqg(dh, p, q, g);
 791     p = g = q = NULL;
 792 
 793 cleanup:
 794     BN_free(p);
 795     BN_free(q);
 796     BN_free(g);
 797     return dh;
 798 }
 799 
 800 static krb5_error_code
 801 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
 802 {
 803     krb5_error_code retval = ENOMEM;
 804 
 805     plgctx->dh_1024 = make_dhprime(pkinit_1024_dhprime,
 806         sizeof(pkinit_1024_dhprime));
 807     if (plgctx->dh_1024 == NULL)
 808         goto cleanup;







 809 
 810     plgctx->dh_2048 = make_dhprime(pkinit_2048_dhprime,
 811         sizeof(pkinit_2048_dhprime));
 812     if (plgctx->dh_2048 == NULL)
 813         goto cleanup;







 814 
 815     plgctx->dh_4096 = make_dhprime(pkinit_4096_dhprime,
 816         sizeof(pkinit_4096_dhprime));
 817     if (plgctx->dh_4096 == NULL)
 818         goto cleanup;







 819 
 820     retval = 0;
 821 
 822 cleanup:
 823     if (retval)
 824         pkinit_fini_dh_params(plgctx);
 825 
 826     return retval;
 827 }
 828 
 829 static void
 830 pkinit_fini_dh_params(pkinit_plg_crypto_context plgctx)
 831 {
 832     if (plgctx->dh_1024 != NULL)
 833         DH_free(plgctx->dh_1024);
 834     if (plgctx->dh_2048 != NULL)
 835         DH_free(plgctx->dh_2048);
 836     if (plgctx->dh_4096 != NULL)
 837         DH_free(plgctx->dh_4096);
 838 


 959 cms_signeddata_create(krb5_context context,
 960                       pkinit_plg_crypto_context plg_cryptoctx,
 961                       pkinit_req_crypto_context req_cryptoctx,
 962                       pkinit_identity_crypto_context id_cryptoctx,
 963                       int cms_msg_type,
 964                       int include_certchain,
 965                       unsigned char *data,
 966                       unsigned int data_len,
 967                       unsigned char **signed_data,
 968                       unsigned int *signed_data_len)
 969 {
 970     /* Solaris Kerberos */
 971     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
 972     PKCS7  *p7 = NULL, *inner_p7 = NULL;
 973     PKCS7_SIGNED *p7s = NULL;
 974     PKCS7_SIGNER_INFO *p7si = NULL;
 975     unsigned char *p;
 976     ASN1_TYPE *pkinit_data = NULL;
 977     STACK_OF(X509) * cert_stack = NULL;
 978     ASN1_OCTET_STRING *digest_attr = NULL;
 979     EVP_MD_CTX *ctx = NULL, *ctx2 = NULL;
 980     const EVP_MD *md_tmp = NULL;
 981     unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
 982     unsigned char *digestInfo_buf = NULL, *abuf = NULL;
 983     unsigned int md_len, md_len2, alen, digestInfo_len;
 984     STACK_OF(X509_ATTRIBUTE) * sk;
 985     unsigned char *sig = NULL;
 986     unsigned int sig_len = 0;
 987     X509_ALGOR *alg = NULL;
 988     ASN1_OCTET_STRING *digest = NULL;
 989     unsigned int alg_len = 0, digest_len = 0;
 990     unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
 991     X509 *cert = NULL;
 992     ASN1_OBJECT *oid = NULL;
 993 
 994     /* Solaris Kerberos */
 995     if (signed_data == NULL)
 996         return EINVAL;
 997 
 998     if (signed_data_len == NULL)
 999         return EINVAL;


1003         goto cleanup;
1004     p7->type = OBJ_nid2obj(NID_pkcs7_signed);
1005 
1006     if ((p7s = PKCS7_SIGNED_new()) == NULL)
1007         goto cleanup;
1008     p7->d.sign = p7s;
1009     if (!ASN1_INTEGER_set(p7s->version, 3))
1010         goto cleanup;
1011 
1012     /* create a cert chain that has at least the signer's certificate */
1013     if ((cert_stack = sk_X509_new_null()) == NULL)
1014         goto cleanup;
1015 
1016     cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
1017     if (!include_certchain) {
1018         pkiDebug("only including signer's certificate\n");
1019         sk_X509_push(cert_stack, X509_dup(cert));
1020     } else {
1021         /* create a cert chain */
1022         X509_STORE *certstore = NULL;
1023         X509_STORE_CTX *certctx;
1024         STACK_OF(X509) *certstack = NULL;
1025         char buf[DN_BUF_LEN];
1026         int i = 0, size = 0;
1027 
1028         if ((certstore = X509_STORE_new()) == NULL)
1029             goto cleanup;
1030         if ((certctx = X509_STORE_CTX_new()) == NULL)
1031             goto cleanup;
1032         pkiDebug("building certificate chain\n");
1033         X509_STORE_set_verify_cb(certstore, openssl_callback);
1034         X509_STORE_CTX_init(certctx, certstore, cert,
1035                             id_cryptoctx->intermediateCAs);
1036         X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs);
1037         /* Solaris Kerberos */
1038         if (X509_verify_cert(certctx) <= 0) {
1039             pkiDebug("failed to create a certificate chain: %s\n",
1040             X509_verify_cert_error_string(X509_STORE_CTX_get_error(certctx)));
1041             if (!sk_X509_num(id_cryptoctx->trustedCAs))
1042                 pkiDebug("No trusted CAs found. Check your X509_anchors\n");
1043             goto cleanup;
1044         }
1045         certstack = X509_STORE_CTX_get1_chain(certctx);
1046         size = sk_X509_num(certstack);
1047         pkiDebug("size of certificate chain = %d\n", size);
1048         for(i = 0; i < size - 1; i++) {
1049             X509 *x = sk_X509_value(certstack, i);
1050             X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
1051             pkiDebug("cert #%d: %s\n", i, buf);
1052             sk_X509_push(cert_stack, X509_dup(x));
1053         }
1054         X509_STORE_CTX_free(certctx);
1055         X509_STORE_free(certstore);
1056         sk_X509_pop_free(certstack, X509_free);
1057     }
1058     p7s->cert = cert_stack;
1059 
1060     /* fill-in PKCS7_SIGNER_INFO */
1061     if ((p7si = PKCS7_SIGNER_INFO_new()) == NULL)
1062         goto cleanup;
1063     if (!ASN1_INTEGER_set(p7si->version, 1))
1064         goto cleanup;
1065     if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
1066                        X509_get_issuer_name(cert)))
1067         goto cleanup;
1068     /* because ASN1_INTEGER_set is used to set a 'long' we will do
1069      * things the ugly way. */
1070     ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
1071     if (!(p7si->issuer_and_serial->serial =
1072           ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
1073         goto cleanup;
1074 
1075     /* will not fill-out EVP_PKEY because it's on the smartcard */
1076 
1077     /* Set digest algs */
1078     p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
1079 
1080     if (p7si->digest_alg->parameter != NULL)
1081         ASN1_TYPE_free(p7si->digest_alg->parameter);
1082     if ((p7si->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
1083         goto cleanup;
1084     p7si->digest_alg->parameter->type = V_ASN1_NULL;
1085 
1086     /* Set sig algs */
1087     if (p7si->digest_enc_alg->parameter != NULL)
1088         ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
1089     p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
1090     if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
1091         goto cleanup;
1092     p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
1093 
1094     /* pick the correct oid for the eContentInfo */
1095     oid = pkinit_pkcs7type2oid(plg_cryptoctx, cms_msg_type);
1096     if (oid == NULL)
1097         goto cleanup;
1098 
1099     if (cms_msg_type == CMS_SIGN_DRAFT9) {
1100         /* don't include signed attributes for pa-type 15 request */
1101         abuf = data;
1102         alen = data_len;
1103     } else {
1104         /* add signed attributes */
1105         /* compute sha1 digest over the EncapsulatedContentInfo */
1106         ctx = EVP_MD_CTX_new();
1107         if (ctx == NULL)
1108             goto cleanup2;
1109         EVP_MD_CTX_init(ctx);
1110         EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
1111         EVP_DigestUpdate(ctx, data, data_len);
1112         md_tmp = EVP_MD_CTX_md(ctx);
1113         EVP_DigestFinal_ex(ctx, md_data, &md_len);
1114         EVP_MD_CTX_free(ctx);
1115         ctx = NULL;
1116 
1117         /* create a message digest attr */
1118         digest_attr = ASN1_OCTET_STRING_new();
1119         ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
1120         PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
1121                                    V_ASN1_OCTET_STRING, (char *) digest_attr);
1122 
1123         /* create a content-type attr */
1124         PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
1125                                    V_ASN1_OBJECT, oid);
1126 
1127         /* create the signature over signed attributes. get DER encoded value */
1128         /* This is the place where smartcard signature needs to be calculated */
1129         sk = p7si->auth_attr;
1130         alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
1131                              ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
1132         if (abuf == NULL)
1133             goto cleanup2;
1134     }
1135 
1136 #ifndef WITHOUT_PKCS11
1137     /* Some tokens can only do RSAEncryption without sha1 hash */
1138     /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
1139      * function and the hash value into an ASN.1 value of type DigestInfo
1140      * DigestInfo::=SEQUENCE {
1141      *  digestAlgorithm  AlgorithmIdentifier,
1142      *  digest OCTET STRING }
1143      */
1144     if (id_cryptoctx->pkcs11_method == 1 &&
1145             id_cryptoctx->mech == CKM_RSA_PKCS) {
1146         pkiDebug("mech = CKM_RSA_PKCS\n");
1147         ctx2 = EVP_MD_CTX_new();
1148         if (ctx2 == NULL)
1149             goto cleanup2;
1150         EVP_MD_CTX_init(ctx2);
1151         /* if this is not draft9 request, include digest signed attribute */
1152         if (cms_msg_type != CMS_SIGN_DRAFT9)
1153             EVP_DigestInit_ex(ctx2, md_tmp, NULL);
1154         else
1155             EVP_DigestInit_ex(ctx2, EVP_sha1(), NULL);
1156         EVP_DigestUpdate(ctx2, abuf, alen);
1157         EVP_DigestFinal_ex(ctx2, md_data2, &md_len2);
1158         EVP_MD_CTX_free(ctx2);
1159         ctx2 = NULL;
1160 
1161         alg = X509_ALGOR_new();
1162         if (alg == NULL)
1163             goto cleanup2;
1164         alg->algorithm = OBJ_nid2obj(NID_sha1);
1165         alg->parameter = NULL;
1166         alg_len = i2d_X509_ALGOR(alg, NULL);
1167         alg_buf = (unsigned char *)malloc(alg_len);
1168         if (alg_buf == NULL)
1169             goto cleanup2;
1170 
1171         digest = ASN1_OCTET_STRING_new();
1172         if (digest == NULL)
1173             goto cleanup2;
1174         ASN1_OCTET_STRING_set(digest, md_data2, (int)md_len2);
1175         digest_len = i2d_ASN1_OCTET_STRING(digest, NULL);
1176         digest_buf = (unsigned char *)malloc(digest_len);
1177         if (digest_buf == NULL)
1178             goto cleanup2;
1179 


1273     }
1274     retval = 0;
1275 
1276 #ifdef DEBUG_ASN1
1277     if (cms_msg_type == CMS_SIGN_CLIENT) {
1278         print_buffer_bin(*signed_data, *signed_data_len,
1279                          "/tmp/client_pkcs7_signeddata");
1280     } else {
1281         if (cms_msg_type == CMS_SIGN_SERVER) {
1282             print_buffer_bin(*signed_data, *signed_data_len,
1283                              "/tmp/kdc_pkcs7_signeddata");
1284         } else {
1285             print_buffer_bin(*signed_data, *signed_data_len,
1286                              "/tmp/draft9_pkcs7_signeddata");
1287         }
1288     }
1289 #endif
1290 
1291   cleanup2:
1292     if (cms_msg_type != CMS_SIGN_DRAFT9)
1293         if (ctx != NULL)
1294                 EVP_MD_CTX_free(ctx);
1295 #ifndef WITHOUT_PKCS11
1296     if (id_cryptoctx->pkcs11_method == 1 &&
1297             id_cryptoctx->mech == CKM_RSA_PKCS) {
1298         if (ctx2 != NULL)
1299                 EVP_MD_CTX_free(ctx2);
1300         if (digest_buf != NULL)
1301             free(digest_buf);
1302         if (digestInfo_buf != NULL)
1303             free(digestInfo_buf);
1304         if (alg_buf != NULL)
1305             free(alg_buf);
1306         if (digest != NULL)
1307             ASN1_OCTET_STRING_free(digest);
1308     }
1309 #endif
1310     if (alg != NULL)
1311         X509_ALGOR_free(alg);
1312   cleanup:
1313     if (p7 != NULL)
1314         PKCS7_free(p7);
1315     if (sig != NULL)
1316         free(sig);
1317 
1318     return retval;
1319 }


1325                       pkinit_identity_crypto_context idctx,
1326                       int cms_msg_type,
1327                       int require_crl_checking,
1328                       unsigned char *signed_data,
1329                       unsigned int signed_data_len,
1330                       unsigned char **data,
1331                       unsigned int *data_len,
1332                       unsigned char **authz_data,
1333                       unsigned int *authz_data_len)
1334 {
1335     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
1336     PKCS7 *p7 = NULL;
1337     BIO *out = NULL;
1338     int flags = PKCS7_NOVERIFY, i = 0;
1339     unsigned int vflags = 0, size = 0;
1340     const unsigned char *p = signed_data;
1341     STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
1342     PKCS7_SIGNER_INFO *si = NULL;
1343     X509 *x = NULL;
1344     X509_STORE *store = NULL;
1345     X509_STORE_CTX *cert_ctx;
1346     STACK_OF(X509) *intermediateCAs = NULL;
1347     STACK_OF(X509_CRL) *revoked = NULL;
1348     STACK_OF(X509) *verified_chain = NULL;
1349     ASN1_OBJECT *oid = NULL;
1350     krb5_external_principal_identifier **krb5_verified_chain = NULL;
1351     krb5_data *authz = NULL;
1352     char buf[DN_BUF_LEN];
1353 
1354 #ifdef DEBUG_ASN1
1355     print_buffer_bin(signed_data, signed_data_len,
1356                      "/tmp/client_received_pkcs7_signeddata");
1357 #endif
1358 
1359     /* Do this early enough to create the shadow OID for pkcs7-data if needed */
1360     oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
1361     if (oid == NULL)
1362         goto cleanup;
1363 
1364     /* decode received PKCS7 message */
1365     if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {


1369         pkiDebug("%s: failed to decode message: %s\n",
1370                  __FUNCTION__, ERR_error_string(err, NULL));
1371         goto cleanup;
1372     }
1373 
1374     /* verify that the received message is PKCS7 SignedData message */
1375     if (OBJ_obj2nid(p7->type) != NID_pkcs7_signed) {
1376         pkiDebug("Expected id-signedData PKCS7 msg (received type = %d)\n",
1377                  OBJ_obj2nid(p7->type));
1378         krb5_set_error_message(context, retval, "wrong oid\n");
1379         goto cleanup;
1380     }
1381 
1382     /* setup to verify X509 certificate used to sign PKCS7 message */
1383     if (!(store = X509_STORE_new()))
1384         goto cleanup;
1385 
1386     /* check if we are inforcing CRL checking */
1387     vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
1388     if (require_crl_checking)
1389         X509_STORE_set_verify_cb(store, openssl_callback);
1390     else
1391         X509_STORE_set_verify_cb(store, openssl_callback_ignore_crls);
1392     X509_STORE_set_flags(store, vflags);
1393 
1394     /* get the signer's information from the PKCS7 message */
1395     if ((si_sk = PKCS7_get_signer_info(p7)) == NULL)
1396         goto cleanup;
1397     if ((si = sk_PKCS7_SIGNER_INFO_value(si_sk, 0)) == NULL)
1398         goto cleanup;
1399     if ((x = PKCS7_cert_from_signer_info(p7, si)) == NULL)
1400         goto cleanup;
1401 
1402     /* create available CRL information (get local CRLs and include CRLs
1403      * received in the PKCS7 message
1404      */
1405     if (idctx->revoked == NULL)
1406         revoked = p7->d.sign->crl;
1407     else if (p7->d.sign->crl == NULL)
1408         revoked = idctx->revoked;
1409     else {
1410         size = sk_X509_CRL_num(idctx->revoked);
1411         revoked = sk_X509_CRL_new_null();


1422     if (idctx->intermediateCAs == NULL)
1423         intermediateCAs = p7->d.sign->cert;
1424     else if (p7->d.sign->cert == NULL)
1425         intermediateCAs = idctx->intermediateCAs;
1426     else {
1427         size = sk_X509_num(idctx->intermediateCAs);
1428         intermediateCAs = sk_X509_new_null();
1429         for (i = 0; i < size; i++) {
1430             sk_X509_push(intermediateCAs,
1431                 sk_X509_value(idctx->intermediateCAs, i));
1432         }
1433         size = sk_X509_num(p7->d.sign->cert);
1434         for (i = 0; i < size; i++) {
1435             sk_X509_push(intermediateCAs, sk_X509_value(p7->d.sign->cert, i));
1436         }
1437     }
1438 
1439     /* initialize x509 context with the received certificate and
1440      * trusted and intermediate CA chains and CRLs
1441      */
1442     if ((cert_ctx = X509_STORE_CTX_new()) == NULL)
1443         goto cleanup;
1444     if (!X509_STORE_CTX_init(cert_ctx, store, x, intermediateCAs))
1445         goto cleanup;
1446 
1447     X509_STORE_CTX_set0_crls(cert_ctx, revoked);
1448 
1449     /* add trusted CAs certificates for cert verification */
1450     if (idctx->trustedCAs != NULL)
1451         X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs);
1452     else {
1453         pkiDebug("unable to find any trusted CAs\n");
1454         goto cleanup;
1455     }
1456 #ifdef DEBUG_CERTCHAIN
1457     if (intermediateCAs != NULL) {
1458         size = sk_X509_num(intermediateCAs);
1459         pkiDebug("untrusted cert chain of size %d\n", size);
1460         for (i = 0; i < size; i++) {
1461             X509_NAME_oneline(X509_get_subject_name(
1462                 sk_X509_value(intermediateCAs, i)), buf, sizeof(buf));
1463             pkiDebug("cert #%d: %s\n", i, buf);
1464         }
1465     }
1466     if (idctx->trustedCAs != NULL) {
1467         size = sk_X509_num(idctx->trustedCAs);
1468         pkiDebug("trusted cert chain of size %d\n", size);
1469         for (i = 0; i < size; i++) {
1470             X509_NAME_oneline(X509_get_subject_name(
1471                 sk_X509_value(idctx->trustedCAs, i)), buf, sizeof(buf));
1472             pkiDebug("cert #%d: %s\n", i, buf);
1473         }
1474     }
1475     if (revoked != NULL) {
1476         size = sk_X509_CRL_num(revoked);
1477         pkiDebug("CRL chain of size %d\n", size);
1478         for (i = 0; i < size; i++) {
1479             X509_CRL *crl = sk_X509_CRL_value(revoked, i);
1480             X509_NAME_oneline(X509_CRL_get_issuer(crl), buf, sizeof(buf));
1481             pkiDebug("crls by CA #%d: %s\n", i , buf);
1482         }
1483     }
1484 #endif
1485 
1486     i = X509_verify_cert(cert_ctx);
1487     if (i <= 0) {
1488         int j = X509_STORE_CTX_get_error(cert_ctx);
1489 
1490         reqctx->received_cert = X509_dup(
1491             X509_STORE_CTX_get_current_cert(cert_ctx));
1492         switch(j) {
1493             case X509_V_ERR_CERT_REVOKED:
1494                 retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
1495                 break;
1496             case X509_V_ERR_UNABLE_TO_GET_CRL:
1497                 retval = KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN;
1498                 break;
1499             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1500             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1501                 retval = KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE;
1502                 break;
1503             default:
1504                 retval = KRB5KDC_ERR_INVALID_CERTIFICATE;
1505         }
1506         X509_NAME_oneline(X509_get_subject_name(
1507             reqctx->received_cert), buf, sizeof(buf));
1508         pkiDebug("problem with cert DN = %s (error=%d) %s\n", buf, j,
1509                  X509_verify_cert_error_string(j));
1510         krb5_set_error_message(context, retval, "%s\n",
1511             X509_verify_cert_error_string(j));
1512 #ifdef DEBUG_CERTCHAIN
1513         size = sk_X509_num(p7->d.sign->cert);
1514         pkiDebug("received cert chain of size %d\n", size);
1515         for (j = 0; j < size; j++) {
1516             X509 *tmp_cert = sk_X509_value(p7->d.sign->cert, j);
1517             X509_NAME_oneline(X509_get_subject_name(tmp_cert), buf, sizeof(buf));
1518             pkiDebug("cert #%d: %s\n", j, buf);
1519         }
1520 #endif
1521     } else {
1522         /* retrieve verified certificate chain */
1523         if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
1524             verified_chain = X509_STORE_CTX_get1_chain(cert_ctx);
1525     }
1526     X509_STORE_CTX_free(cert_ctx);
1527     if (i <= 0)
1528         goto cleanup;
1529 
1530     out = BIO_new(BIO_s_mem());
1531     if (cms_msg_type == CMS_SIGN_DRAFT9)
1532         flags |= PKCS7_NOATTR;
1533     if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
1534         int valid_oid = 0;
1535 
1536         if (!OBJ_cmp(p7->d.sign->contents->type, oid))
1537             valid_oid = 1;
1538         else if (cms_msg_type == CMS_SIGN_DRAFT9) {
1539             /*
1540              * Various implementations of the pa-type 15 request use
1541              * different OIDS.  We check that the returned object
1542              * has any of the acceptable OIDs
1543              */
1544             ASN1_OBJECT *client_oid = NULL, *server_oid = NULL, *rsa_oid = NULL;
1545             client_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_CLIENT);
1546             server_oid = pkinit_pkcs7type2oid(plgctx, CMS_SIGN_SERVER);
1547             rsa_oid = pkinit_pkcs7type2oid(plgctx, CMS_ENVEL_SERVER);
1548             if (!OBJ_cmp(p7->d.sign->contents->type, client_oid) ||
1549                 !OBJ_cmp(p7->d.sign->contents->type, server_oid) ||
1550                 !OBJ_cmp(p7->d.sign->contents->type, rsa_oid))
1551                 valid_oid = 1;
1552         }
1553 
1554         if (valid_oid)
1555             pkiDebug("PKCS7 Verification successful\n");
1556         else {
1557             const ASN1_OBJECT *etype = p7->d.sign->contents->type;
1558             pkiDebug("wrong oid in eContentType\n");
1559             print_buffer((unsigned char *)OBJ_get0_data(etype),
1560                 OBJ_length(etype));
1561             retval = KRB5KDC_ERR_PREAUTH_FAILED;
1562             krb5_set_error_message(context, retval, "wrong oid\n");
1563             goto cleanup;
1564         }
1565     }
1566     else {
1567         unsigned long err = ERR_peek_error();
1568         switch(ERR_GET_REASON(err)) {
1569             case PKCS7_R_DIGEST_FAILURE:
1570                 retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
1571                 break;
1572             case PKCS7_R_SIGNATURE_FAILURE:
1573             default:
1574                 retval = KRB5KDC_ERR_INVALID_SIG;
1575         }
1576         pkiDebug("PKCS7 Verification failure\n");
1577         krb5_set_error_message(context, retval, "%s\n",
1578                                ERR_error_string(err, NULL));
1579         goto cleanup;
1580     }


2282     }
2283 
2284     return retval;
2285 }
2286 
2287 /* ARGSUSED */
2288 krb5_error_code
2289 client_create_dh(krb5_context context,
2290                  pkinit_plg_crypto_context plg_cryptoctx,
2291                  pkinit_req_crypto_context cryptoctx,
2292                  pkinit_identity_crypto_context id_cryptoctx,
2293                  int dh_size,
2294                  unsigned char **dh_params,
2295                  unsigned int *dh_params_len,
2296                  unsigned char **dh_pubkey,
2297                  unsigned int *dh_pubkey_len)
2298 {
2299     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2300     unsigned char *buf = NULL;
2301     int dh_err = 0;
2302     ASN1_INTEGER *asn_pub_key = NULL;
2303     BIGNUM *p, *g, *q;
2304     const BIGNUM *pub_key;
2305 
2306     if (cryptoctx->dh == NULL) {
2307         if ((cryptoctx->dh = DH_new()) == NULL)
2308             goto cleanup;
2309         if ((g = BN_new()) == NULL || (q = BN_new()) == NULL)

2310             goto cleanup;
2311 
2312         switch(dh_size) {
2313             case 1024:
2314                 pkiDebug("client uses 1024 DH keys\n");
2315                 cryptoctx->dh = make_dhprime(pkinit_1024_dhprime,
2316                     sizeof(pkinit_1024_dhprime));
2317                 break;
2318             case 2048:
2319                 pkiDebug("client uses 2048 DH keys\n");
2320                 cryptoctx->dh = make_dhprime(pkinit_2048_dhprime,
2321                     sizeof(pkinit_2048_dhprime));
2322                 break;
2323             case 4096:
2324                 pkiDebug("client uses 4096 DH keys\n");
2325                 cryptoctx->dh = make_dhprime(pkinit_4096_dhprime,
2326                     sizeof(pkinit_4096_dhprime));
2327                 break;
2328         }
2329         if (cryptoctx->dh == NULL)
2330                 goto cleanup;
2331     }
2332 




2333     DH_generate_key(cryptoctx->dh);
2334     DH_get0_key(cryptoctx->dh, &pub_key, NULL);
2335 
2336 /* Solaris Kerberos */
2337 #ifdef DEBUG
2338     DH_check(cryptoctx->dh, &dh_err);
2339     if (dh_err != 0) {
2340         pkiDebug("Warning: dh_check failed with %d\n", dh_err);
2341         if (dh_err & DH_CHECK_P_NOT_PRIME)
2342             pkiDebug("p value is not prime\n");
2343         if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
2344             pkiDebug("p value is not a safe prime\n");
2345         if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
2346             pkiDebug("unable to check the generator value\n");
2347         if (dh_err & DH_NOT_SUITABLE_GENERATOR)
2348             pkiDebug("the g value is not a generator\n");
2349     }
2350 #endif
2351 #ifdef DEBUG_DH
2352     print_dh(cryptoctx->dh, "client's DH params\n");
2353     print_pubkey(pub_key, "client's pub_key=");
2354 #endif
2355 
2356     DH_check_pub_key(cryptoctx->dh, pub_key, &dh_err);
2357     if (dh_err != 0) {
2358         pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
2359         goto cleanup;
2360     }
2361 
2362     /* pack DHparams */
2363     /* aglo: usually we could just call i2d_DHparams to encode DH params
2364      * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
2365      */
2366     DH_get0_pqg(cryptoctx->dh, (const BIGNUM **)&p, (const BIGNUM **)&q,
2367         (const BIGNUM **)&g);
2368     retval = pkinit_encode_dh_params(p, g, q, dh_params, dh_params_len);
2369     if (retval)
2370         goto cleanup;
2371 
2372     /* pack DH public key */
2373     /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2374      * encoding shall be used as the contents (the value) of the
2375      * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2376      * data element
2377      */
2378     if ((asn_pub_key = BN_to_ASN1_INTEGER(pub_key, NULL)) == NULL)
2379         goto cleanup;
2380     *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
2381     if ((buf = *dh_pubkey = (unsigned char *)
2382         malloc((size_t) *dh_pubkey_len)) == NULL) {
2383             retval = ENOMEM;
2384             goto cleanup;
2385     }
2386     i2d_ASN1_INTEGER(asn_pub_key, &buf);
2387 
2388     if (asn_pub_key != NULL)
2389         ASN1_INTEGER_free(asn_pub_key);
2390 
2391     retval = 0;
2392     return retval;
2393 
2394   cleanup:
2395     if (cryptoctx->dh != NULL)
2396         DH_free(cryptoctx->dh);
2397     cryptoctx->dh = NULL;
2398     if (*dh_params != NULL)
2399         free(*dh_params);
2400     *dh_params = NULL;
2401     if (*dh_pubkey != NULL)
2402         free(*dh_pubkey);
2403     *dh_pubkey = NULL;
2404     if (asn_pub_key != NULL)
2405         ASN1_INTEGER_free(asn_pub_key);
2406 
2407     return retval;
2408 }
2409 
2410 /* ARGSUSED */
2411 krb5_error_code
2412 client_process_dh(krb5_context context,
2413                   pkinit_plg_crypto_context plg_cryptoctx,
2414                   pkinit_req_crypto_context cryptoctx,
2415                   pkinit_identity_crypto_context id_cryptoctx,
2416                   unsigned char *subjectPublicKey_data,
2417                   unsigned int subjectPublicKey_length,
2418                   unsigned char **client_key,
2419                   unsigned int *client_key_len)
2420 {
2421     /* Solaris Kerberos */
2422     krb5_error_code retval = KRB5_PREAUTH_FAILED;
2423     BIGNUM *server_pub_key = NULL;
2424     ASN1_INTEGER *pub_key = NULL;
2425     const unsigned char *p = NULL;


2473         ASN1_INTEGER_free(pub_key);
2474     if (data != NULL)
2475         free (data);
2476 
2477     return retval;
2478 }
2479 
2480 /* ARGSUSED */
2481 krb5_error_code
2482 server_check_dh(krb5_context context,
2483                 pkinit_plg_crypto_context cryptoctx,
2484                 pkinit_req_crypto_context req_cryptoctx,
2485                 pkinit_identity_crypto_context id_cryptoctx,
2486                 krb5_octet_data *dh_params,
2487                 int minbits)
2488 {
2489     DH *dh = NULL;
2490     unsigned char *tmp = NULL;
2491     int dh_prime_bits;
2492     krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
2493     const BIGNUM *p, *g, *q, *p2;
2494 
2495     tmp = dh_params->data;
2496     dh = DH_new();
2497     dh = pkinit_decode_dh_params(&dh, &tmp, dh_params->length);
2498     if (dh == NULL) {
2499         pkiDebug("failed to decode dhparams\n");
2500         goto cleanup;
2501     }
2502 
2503     DH_get0_pqg(dh, &p, &q, &g);
2504 
2505     /* KDC SHOULD check to see if the key parameters satisfy its policy */
2506     dh_prime_bits = BN_num_bits(p);
2507     if (minbits && dh_prime_bits < minbits) {
2508         pkiDebug("client sent dh params with %d bits, we require %d\n",
2509                  dh_prime_bits, minbits);
2510         goto cleanup;
2511     }
2512 
2513     /* check dhparams is group 2 */
2514     DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
2515     if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2516         retval = 0;
2517         goto cleanup;
2518     }
2519 
2520     /* check dhparams is group 14 */
2521     DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
2522     if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2523         retval = 0;
2524         goto cleanup;
2525     }
2526 
2527     /* check dhparams is group 16 */
2528     DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
2529     if (pkinit_check_dh_params(p2, p, g, q) == 0) {
2530         retval = 0;
2531         goto cleanup;
2532     }
2533 
2534   cleanup:
2535     if (retval == 0)
2536         req_cryptoctx->dh = dh;
2537     else
2538         DH_free(dh);
2539 
2540     return retval;
2541 }
2542 
2543 /* kdc's dh function */
2544 /* ARGSUSED */
2545 krb5_error_code
2546 server_process_dh(krb5_context context,
2547                   pkinit_plg_crypto_context plg_cryptoctx,
2548                   pkinit_req_crypto_context cryptoctx,
2549                   pkinit_identity_crypto_context id_cryptoctx,
2550                   unsigned char *data,
2551                   unsigned int data_len,
2552                   unsigned char **dh_pubkey,
2553                   unsigned int *dh_pubkey_len,
2554                   unsigned char **server_key,
2555                   unsigned int *server_key_len)
2556 {
2557     /* Solaris Kerberos */
2558     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2559     DH *dh = NULL, *dh_server = NULL;
2560     const BIGNUM *p, *g, *q, *s_pub_key;
2561     BIGNUM *pub_key;
2562     unsigned char *s = NULL;
2563     ASN1_INTEGER *asn_pub_key = NULL;
2564 
2565     /* get client's received DH parameters that we saved in server_check_dh */
2566     dh = cryptoctx->dh;
2567 
2568     dh_server = DH_new();
2569     if (dh_server == NULL)
2570         goto cleanup;
2571     DH_get0_pqg(dh, &p, &g, &q);
2572     DH_set0_pqg(dh_server, BN_dup(p), BN_dup(g), BN_dup(q));

2573 
2574     /* decode client's public key */
2575     s = data;
2576     asn_pub_key = d2i_ASN1_INTEGER(NULL,
2577         (const unsigned char **)&s, (int)data_len);
2578     if (asn_pub_key == NULL)
2579         goto cleanup;
2580     pub_key = ASN1_INTEGER_to_BN(asn_pub_key, NULL);
2581     if (pub_key == NULL)
2582         goto cleanup;
2583     DH_set0_key(dh, pub_key, NULL);
2584     ASN1_INTEGER_free(asn_pub_key);


2585 
2586     if (!DH_generate_key(dh_server))
2587         goto cleanup;
2588 
2589     /* generate DH session key */
2590     *server_key_len = DH_size(dh_server);
2591     if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len))
2592         == NULL)
2593             goto cleanup;
2594     DH_compute_key(*server_key, pub_key, dh_server);
2595     DH_get0_key(dh_server, &s_pub_key, NULL);
2596 
2597 #ifdef DEBUG_DH
2598     print_dh(dh_server, "client&server's DH params\n");
2599     print_pubkey(pub_key, "client's pub_key=");
2600     print_pubkey(s_pub_key, "server's pub_key=");
2601     pkiDebug("server secret key=");
2602     print_buffer(*server_key, *server_key_len);
2603 #endif
2604 
2605     /* KDC reply */
2606     /* pack DH public key */
2607     /* Diffie-Hellman public key must be ASN1 encoded as an INTEGER; this
2608      * encoding shall be used as the contents (the value) of the
2609      * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
2610      * data element
2611      */
2612     if ((asn_pub_key = BN_to_ASN1_INTEGER(s_pub_key, NULL)) == NULL)
2613         goto cleanup;
2614     *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
2615     if ((s = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len))
2616         == NULL)
2617             goto cleanup;
2618     i2d_ASN1_INTEGER(asn_pub_key, &s);
2619     if (asn_pub_key != NULL)
2620         ASN1_INTEGER_free(asn_pub_key);
2621 
2622     retval = 0;
2623 
2624     if (dh_server != NULL)
2625         DH_free(dh_server);
2626     return retval;
2627 
2628   cleanup:
2629     if (dh_server != NULL)
2630         DH_free(dh_server);
2631     if (*dh_pubkey != NULL)
2632         free(*dh_pubkey);
2633     if (*server_key != NULL)
2634         free(*server_key);
2635 
2636     return retval;
2637 }
2638 
2639 /*
2640  * Solaris Kerberos:
2641  * Add locking around did_init to make it MT-safe.
2642  */
2643 static krb5_error_code
2644 openssl_init()
2645 {
2646     krb5_error_code ret = 0;
2647     static int did_init = 0;
2648     static k5_mutex_t init_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
2649 
2650     ret = k5_mutex_lock(&init_mutex);
2651     if (ret == 0) {
2652         if (!did_init) {
2653             /* initialize openssl routines */
2654 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2655             /*
2656              * As of version 1.1.0, OpenSSL will automatically allocate
2657              * resources as-needed.
2658              */
2659             CRYPTO_malloc_init();
2660             ERR_load_crypto_strings();
2661             OpenSSL_add_all_algorithms();
2662 #endif
2663             did_init++;
2664         }
2665         k5_mutex_unlock(&init_mutex);
2666     }
2667     return (ret);
2668 }
2669 
2670 static krb5_error_code
2671 pkinit_encode_dh_params(const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
2672                         unsigned char **buf, unsigned int *buf_len)
2673 {
2674     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
2675     int bufsize = 0, r = 0;
2676     unsigned char *tmp = NULL;
2677     ASN1_INTEGER *ap = NULL, *ag = NULL, *aq = NULL;
2678 
2679     if ((ap = BN_to_ASN1_INTEGER(p, NULL)) == NULL)
2680         goto cleanup;
2681     if ((ag = BN_to_ASN1_INTEGER(g, NULL)) == NULL)
2682         goto cleanup;
2683     if ((aq = BN_to_ASN1_INTEGER(q, NULL)) == NULL)
2684         goto cleanup;
2685     bufsize = i2d_ASN1_INTEGER(ap, NULL);
2686     bufsize += i2d_ASN1_INTEGER(ag, NULL);
2687     bufsize += i2d_ASN1_INTEGER(aq, NULL);
2688 
2689     r = ASN1_object_size(1, bufsize, V_ASN1_SEQUENCE);
2690 
2691     tmp = *buf = (unsigned char *)malloc((size_t) r);


2696 
2697     i2d_ASN1_INTEGER(ap, &tmp);
2698     i2d_ASN1_INTEGER(ag, &tmp);
2699     i2d_ASN1_INTEGER(aq, &tmp);
2700 
2701     *buf_len = r;
2702 
2703     retval = 0;
2704 
2705 cleanup:
2706     if (ap != NULL)
2707         ASN1_INTEGER_free(ap);
2708     if (ag != NULL)
2709         ASN1_INTEGER_free(ag);
2710     if (aq != NULL)
2711         ASN1_INTEGER_free(aq);
2712 
2713     return retval;
2714 }
2715 
2716 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2717 
2718 static DH *
2719 pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
2720 {
2721     ASN1_INTEGER ai, *aip = NULL;
2722     long length = (long) len;
2723 
2724     M_ASN1_D2I_vars(a, DH *, DH_new);
2725 
2726     M_ASN1_D2I_Init();
2727     M_ASN1_D2I_start_sequence();
2728     aip = &ai;
2729     ai.data = NULL;
2730     ai.length = 0;
2731     M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2732     if (aip == NULL)
2733         return NULL;
2734     else {
2735         (*a)->p = ASN1_INTEGER_to_BN(aip, NULL);
2736         if ((*a)->p == NULL)
2737             return NULL;


2757     }
2758     M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
2759     if (aip == NULL)
2760         return NULL;
2761     else {
2762         (*a)->q = ASN1_INTEGER_to_BN(aip, NULL);
2763         if ((*a)->q == NULL)
2764             return NULL;
2765         if (ai.data != NULL) {
2766             OPENSSL_free(ai.data);
2767             ai.data = NULL;
2768             ai.length = 0;
2769         }
2770 
2771     }
2772     M_ASN1_D2I_end_sequence();
2773     M_ASN1_D2I_Finish(a, DH_free, 0);
2774 
2775 }
2776 
2777 #else
2778 
2779 /*
2780  * This is taken from the internal dh_asn1.c file in OpenSSL 1.1, modified to
2781  * make q an optional field.
2782  */
2783 
2784 typedef struct {
2785     ASN1_BIT_STRING *seed;
2786     BIGNUM *counter;
2787 } int_dhvparams;
2788 
2789 typedef struct {
2790     BIGNUM *p;
2791     BIGNUM *q;
2792     BIGNUM *g;
2793     BIGNUM *j;
2794     int_dhvparams *vparams;
2795 } int_dhx942_dh;
2796 
2797 ASN1_SEQUENCE(DHvparams) = {
2798     ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
2799     ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
2800 } static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
2801 
2802 ASN1_SEQUENCE(DHxparams) = {
2803     ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
2804     ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
2805     ASN1_OPT(int_dhx942_dh, q, BIGNUM),
2806     ASN1_OPT(int_dhx942_dh, j, BIGNUM),
2807     ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
2808 } static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
2809 
2810 static DH *
2811 pkinit_decode_dh_params(DH **a, unsigned char **pp, unsigned int len)
2812 {
2813         int_dhx942_dh *params;
2814         DH *dh = *a;
2815 
2816         if (dh == NULL)
2817                 return NULL;
2818 
2819         params = (int_dhx942_dh *)ASN1_item_d2i(NULL,
2820             (const unsigned char **)pp, len, ASN1_ITEM_rptr(DHxparams));
2821         if (params == NULL) {
2822                 DH_free(dh);
2823                 return NULL;
2824         }
2825 
2826         DH_set0_pqg(dh, params->p, params->q, params->g);
2827         params->p = params->q = params->g = NULL;
2828         ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(DHxparams));
2829         return dh;
2830 }
2831 
2832 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
2833 
2834 static krb5_error_code
2835 pkinit_create_sequence_of_principal_identifiers(
2836     krb5_context context,
2837     pkinit_plg_crypto_context plg_cryptoctx,
2838     pkinit_req_crypto_context req_cryptoctx,
2839     pkinit_identity_crypto_context id_cryptoctx,
2840     int type,
2841     krb5_data **out_data)
2842 {
2843     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2844     krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
2845     krb5_data *td_certifiers = NULL, *data = NULL;
2846     krb5_typed_data **typed_data = NULL;
2847 
2848     switch(type) {
2849         case TD_TRUSTED_CERTIFIERS:
2850             retval = create_krb5_trustedCertifiers(context, plg_cryptoctx,
2851                 req_cryptoctx, id_cryptoctx, &krb5_trusted_certifiers);
2852             if (retval) {
2853                 pkiDebug("create_krb5_trustedCertifiers failed\n");


2958 
2959     return retval;
2960 }
2961 
2962 /* ARGSUSED */
2963 krb5_error_code
2964 pkinit_create_td_dh_parameters(krb5_context context,
2965                                pkinit_plg_crypto_context plg_cryptoctx,
2966                                pkinit_req_crypto_context req_cryptoctx,
2967                                pkinit_identity_crypto_context id_cryptoctx,
2968                                pkinit_plg_opts *opts,
2969                                krb5_data **out_data)
2970 {
2971     /* Solaris Kerberos */
2972     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
2973     unsigned int buf1_len = 0, buf2_len = 0, buf3_len = 0, i = 0;
2974     unsigned char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
2975     krb5_typed_data **typed_data = NULL;
2976     krb5_data *data = NULL, *encoded_algId = NULL;
2977     krb5_algorithm_identifier **algId = NULL;
2978     const BIGNUM *p, *q, *g;
2979 
2980     /* Solaris Kerberos */
2981     if (opts->dh_min_bits > 4096) {
2982         retval = EINVAL;
2983         goto cleanup;
2984     }
2985 
2986     if (opts->dh_min_bits <= 1024) {
2987         DH_get0_pqg(plg_cryptoctx->dh_1024, &p, &q, &g);
2988         retval = pkinit_encode_dh_params(p, g, q, &buf1, &buf1_len);

2989         if (retval)
2990             goto cleanup;
2991     }
2992     if (opts->dh_min_bits <= 2048) {
2993         DH_get0_pqg(plg_cryptoctx->dh_2048, &p, &q, &g);
2994         retval = pkinit_encode_dh_params(p, g, q, &buf2, &buf2_len);

2995         if (retval)
2996             goto cleanup;
2997     }
2998     DH_get0_pqg(plg_cryptoctx->dh_4096, &p, &q, &g);
2999     retval = pkinit_encode_dh_params(p, g, q, &buf3, &buf3_len);

3000     if (retval)
3001         goto cleanup;
3002 
3003     if (opts->dh_min_bits <= 1024) {
3004         algId = malloc(4 * sizeof(krb5_algorithm_identifier *));
3005         if (algId == NULL)
3006             goto cleanup;
3007         algId[3] = NULL;
3008         algId[0] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
3009         if (algId[0] == NULL)
3010             goto cleanup;
3011         algId[0]->parameters.data = (unsigned char *)malloc(buf2_len);
3012         if (algId[0]->parameters.data == NULL)
3013             goto cleanup;
3014         (void) memcpy(algId[0]->parameters.data, buf2, buf2_len);
3015         algId[0]->parameters.length = buf2_len;
3016         algId[0]->algorithm = dh_oid;
3017 
3018         algId[1] = (krb5_algorithm_identifier *)malloc(sizeof(krb5_algorithm_identifier));
3019         if (algId[1] == NULL)


3173     if (is == NULL)
3174         goto cleanup;
3175 
3176     status = X509_NAME_cmp(X509_get_issuer_name(kdc_cert), is->issuer);
3177     if (!status) {
3178         status = ASN1_INTEGER_cmp(X509_get_serialNumber(kdc_cert), is->serial);
3179         if (!status)
3180             *valid_kdcPkId = 1;
3181     }
3182 
3183     retval = 0;
3184 cleanup:
3185     X509_NAME_free(is->issuer);
3186     ASN1_INTEGER_free(is->serial);
3187     free(is);
3188 
3189     return retval;
3190 }
3191 
3192 static int
3193 pkinit_check_dh_params(const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1,
3194     const BIGNUM *q1)
3195 {
3196     BIGNUM *g2 = NULL, *q2 = NULL;
3197     /* Solaris Kerberos */
3198     int retval = EINVAL;
3199 
3200     if (!BN_cmp(p1, p2)) {
3201         g2 = BN_new();
3202         BN_set_word(g2, DH_GENERATOR_2);
3203         if (!BN_cmp(g1, g2)) {
3204             q2 = BN_new();
3205             BN_rshift1(q2, p1);
3206             if (!BN_cmp(q1, q2)) {
3207                 pkiDebug("good %d dhparams\n", BN_num_bits(p1));
3208                 retval = 0;
3209             } else
3210                 pkiDebug("bad group 2 q dhparameter\n");
3211             BN_free(q2);
3212         } else
3213             pkiDebug("bad g dhparameter\n");
3214         BN_free(g2);


3218     return retval;
3219 }
3220 
3221 /* ARGSUSED */
3222 krb5_error_code
3223 pkinit_process_td_dh_params(krb5_context context,
3224                             pkinit_plg_crypto_context cryptoctx,
3225                             pkinit_req_crypto_context req_cryptoctx,
3226                             pkinit_identity_crypto_context id_cryptoctx,
3227                             krb5_algorithm_identifier **algId,
3228                             int *new_dh_size)
3229 {
3230     krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3231     int i = 0, use_sent_dh = 0, ok = 0;
3232 
3233     pkiDebug("dh parameters\n");
3234 
3235     while (algId[i] != NULL) {
3236         DH *dh = NULL;
3237         unsigned char *tmp = NULL;
3238         const BIGNUM *p, *g, *q, *p2;
3239         int dh_prime_bits = 0;
3240 
3241         if (algId[i]->algorithm.length != dh_oid.length ||
3242             memcmp(algId[i]->algorithm.data, dh_oid.data, dh_oid.length))
3243             goto cleanup;
3244 
3245         tmp = algId[i]->parameters.data;
3246         dh = DH_new();
3247         dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
3248         dh_prime_bits = DH_bits(dh);
3249         pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
3250                  *new_dh_size, dh_prime_bits);
3251         DH_get0_pqg(dh, &p, &q, &g);
3252         switch(dh_prime_bits) {
3253             case 1024:
3254                 DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
3255                 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3256                     *new_dh_size = 1024;
3257                     ok = 1;
3258                 }
3259                 break;
3260             case 2048:
3261                 DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
3262                 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3263                     *new_dh_size = 2048;
3264                     ok = 1;
3265                 }
3266                 break;
3267             case 4096:
3268                 DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
3269                 if (pkinit_check_dh_params(p2, p, g, q) == 0) {
3270                     *new_dh_size = 4096;
3271                     ok = 1;
3272                 }
3273                 break;
3274             default:
3275                 break;
3276         }
3277         if (!ok) {
3278             DH_check(dh, &retval);
3279             if (retval != 0) {
3280                 pkiDebug("DH parameters provided by server are unacceptable\n");
3281                 retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
3282             }
3283             else {
3284                 use_sent_dh = 1;
3285                 ok = 1;
3286             }
3287         }
3288         if (!use_sent_dh)
3289             DH_free(dh);


3309 /* ARGSUSED */
3310 static int
3311 openssl_callback(int ok, X509_STORE_CTX * ctx)
3312 {
3313 #ifdef DEBUG
3314     if (!ok) {
3315         char buf[DN_BUF_LEN];
3316 
3317         X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf));
3318         pkiDebug("cert = %s\n", buf);
3319         pkiDebug("callback function: %d (%s)\n", ctx->error,
3320                 X509_verify_cert_error_string(ctx->error));
3321     }
3322 #endif
3323     return ok;
3324 }
3325 
3326 static int
3327 openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
3328 {
3329     if (!ok)
3330         return (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL);






3331     return ok;
3332 }
3333 
3334 static ASN1_OBJECT *
3335 pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
3336 {
3337     int nid;
3338 
3339     switch (pkcs7_type) {
3340         case CMS_SIGN_CLIENT:
3341             return cryptoctx->id_pkinit_authData;
3342         case CMS_SIGN_DRAFT9:
3343             /*
3344              * Delay creating this OID until we know we need it.
3345              * It shadows an existing OpenSSL oid.  If it
3346              * is created too early, it breaks things like
3347              * the use of pkcs12 (which uses pkcs7 structures).
3348              * We need this shadow version because our code
3349              * depends on the "other" type to be unknown to the
3350              * OpenSSL code.


3499     ASN1_put_object(&p, 1, (int)(orig_len+oid_len),
3500                     V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
3501 
3502     i2d_ASN1_OBJECT(oid, &p);
3503 
3504     ASN1_put_object(&p, 1, (int)data_len, 0, V_ASN1_CONTEXT_SPECIFIC);
3505     (void) memcpy(p, data, data_len);
3506 
3507     *out_len = tot_len;
3508 
3509     return 0;
3510 }
3511 #endif
3512 
3513 static int
3514 prepare_enc_data(unsigned char *indata,
3515                  int indata_len,
3516                  unsigned char **outdata,
3517                  int *outdata_len)
3518 {
3519     int tag, class;
3520     long tlen, slen;
3521     const uint8_t *p = indata, *oldp;


3522 
3523     /* Top-bit set means that the conversion failed. */
3524     if (ASN1_get_object(&p, &slen, &tag, &class, indata_len) & 0x80)
3525         return EINVAL;
3526     if (tag != V_ASN1_SEQUENCE)
3527         return EINVAL;
3528 
3529     oldp = p;
3530     if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
3531         return EINVAL;
3532     p += tlen;
3533     slen -= (p - oldp);
3534 
3535     if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
3536         return EINVAL;

3537 
3538     *outdata = malloc(tlen);
3539     if (*outdata == NULL)



3540         return ENOMEM;
3541     memcpy(*outdata, p, tlen);
3542     *outdata_len = tlen;
3543 



3544     return 0;
3545 }
3546 
3547 #ifndef WITHOUT_PKCS11
3548 static void *
3549 pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
3550 {
3551     void *handle;
3552     CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
3553 
3554     pkiDebug("loading module \"%s\"... ", modname);
3555     /* Solaris Kerberos */
3556     handle = dlopen(modname, RTLD_NOW | RTLD_GROUP);
3557     if (handle == NULL) {
3558         pkiDebug("not found\n");
3559         return NULL;
3560     }
3561     getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
3562     if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
3563         (void) dlclose(handle);


4555  * You must call pkinit_get_certs before calling pkinit_find_private_key
4556  * (that's because we need the ID of the private key)
4557  *
4558  * pkcs11 says the id of the key doesn't have to match that of the cert, but
4559  * I can't figure out any other way to decide which key to use.
4560  *
4561  * We should only find one key that fits all the requirements.
4562  * If there are more than one, we just take the first one.
4563  */
4564 
4565 /* ARGSUSED */
4566 krb5_error_code
4567 pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
4568                         CK_ATTRIBUTE_TYPE usage,
4569                         CK_OBJECT_HANDLE *objp)
4570 {
4571     CK_OBJECT_CLASS cls;
4572     CK_ATTRIBUTE attrs[4];
4573     CK_ULONG count;
4574     CK_KEY_TYPE keytype;
4575     RSA *rsa;
4576     unsigned int nattrs = 0;
4577     int r;
4578 #ifdef PKINIT_USE_KEY_USAGE
4579     CK_BBOOL true_false;
4580 #endif
4581 
4582     cls = CKO_PRIVATE_KEY;
4583     attrs[nattrs].type = CKA_CLASS;
4584     attrs[nattrs].pValue = &cls;
4585     attrs[nattrs].ulValueLen = sizeof cls;
4586     nattrs++;
4587 
4588 #ifdef PKINIT_USE_KEY_USAGE
4589     /*
4590      * Some cards get confused if you try to specify a key usage,
4591      * so don't, and hope for the best. This will fail if you have
4592      * several keys with the same id and different usages but I have
4593      * not seen this on real cards.
4594      */
4595     true_false = TRUE;


4616                  pkinit_pkcs11_code_to_text(r));
4617         return KRB5KDC_ERR_PREAUTH_FAILED;
4618     }
4619 
4620     r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
4621     id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
4622     pkiDebug("found %d private keys (%s)\n", (int) count, pkinit_pkcs11_code_to_text(r));
4623 
4624     /*
4625      * Solaris Kerberos:
4626      * The CKA_ID may not be correctly set for the private key. For e.g. when
4627      * storing a private key in softtoken pktool(1) doesn't generate or store
4628      * a CKA_ID for the private key. Another way to identify the private key is
4629      * to look for a private key with the same RSA modulus as the public key
4630      * in the certificate.
4631      */
4632     if (r == CKR_OK && count != 1) {
4633 
4634         EVP_PKEY *priv;
4635         X509 *cert;
4636         const BIGNUM *rsan;
4637         unsigned int n_len;
4638         unsigned char *n_bytes;
4639 
4640         cert = sk_X509_value(id_cryptoctx->my_certs, 0);
4641         priv = X509_get_pubkey(cert);
4642         if (priv == NULL) {
4643                 pkiDebug("Failed to extract pub key from cert\n");
4644                 return KRB5KDC_ERR_PREAUTH_FAILED;
4645         }
4646 
4647         nattrs = 0;
4648         cls = CKO_PRIVATE_KEY;
4649         attrs[nattrs].type = CKA_CLASS;
4650         attrs[nattrs].pValue = &cls;
4651         attrs[nattrs].ulValueLen = sizeof cls;
4652         nattrs++;
4653 
4654 #ifdef PKINIT_USE_KEY_USAGE
4655         true_false = TRUE;
4656         attrs[nattrs].type = usage;
4657         attrs[nattrs].pValue = &true_false;
4658         attrs[nattrs].ulValueLen = sizeof true_false;
4659         nattrs++;
4660 #endif
4661 
4662         keytype = CKK_RSA;
4663         attrs[nattrs].type = CKA_KEY_TYPE;
4664         attrs[nattrs].pValue = &keytype;
4665         attrs[nattrs].ulValueLen = sizeof keytype;
4666         nattrs++;
4667 
4668 #if OPENSSL_VERSION_NUMBER < 0x10100000L
4669         rsa = priv->pkey.rsa;
4670         rsan = rsa->n;
4671         n_len = BN_num_bytes(rsan);
4672 #else
4673         rsa = EVP_PKEY_get0_RSA(priv);
4674         RSA_get0_key(rsa, &rsan, NULL, NULL);
4675         n_len = RSA_size(rsa);
4676 #endif
4677         n_bytes = (unsigned char *) malloc((size_t) n_len);
4678         if (n_bytes == NULL) {
4679                 return (ENOMEM);
4680         }
4681 
4682         if (BN_bn2bin(rsan, n_bytes) == 0) {
4683                 free (n_bytes);
4684                 pkiDebug("zero-byte key modulus\n");
4685                 return KRB5KDC_ERR_PREAUTH_FAILED;
4686         }
4687 
4688         attrs[nattrs].type = CKA_MODULUS;
4689         attrs[nattrs].ulValueLen = n_len;
4690         attrs[nattrs].pValue = n_bytes;
4691 
4692         nattrs++;
4693 
4694         r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
4695         free (n_bytes);
4696         if (r != CKR_OK) {
4697                 pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
4698                         pkinit_pkcs11_code_to_text(r));
4699                 return KRB5KDC_ERR_PREAUTH_FAILED;
4700         }
4701 
4702         r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);


4971     /* Solaris Kerberos */
4972     int len;
4973     unsigned char *buf = NULL;
4974     int buf_len = 0;
4975 
4976     /* Solaris Kerberos */
4977     if (out_data == NULL || out_data_len == NULL)
4978         return EINVAL;
4979 
4980     if (cert && !X509_check_private_key(cert, pkey)) {
4981         pkiDebug("private key does not match certificate\n");
4982         /* Solaris Kerberos */
4983         return EINVAL;
4984     }
4985 
4986     buf_len = EVP_PKEY_size(pkey);
4987     buf = (unsigned char *)malloc((size_t) buf_len + 10);
4988     if (buf == NULL)
4989         return ENOMEM;
4990 



4991     len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);

4992     if (len <= 0) {
4993         pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
4994         /* Solaris Kerberos */
4995         free(buf);
4996         return KRB5KRB_ERR_GENERIC;
4997     }
4998     *out_data = buf;
4999     *out_data_len = len;
5000 
5001     return 0;
5002 }
5003 
5004 static krb5_error_code
5005 create_signature(unsigned char **sig, unsigned int *sig_len,
5006                  unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
5007 {
5008     krb5_error_code retval = ENOMEM;
5009     EVP_MD_CTX *md_ctx;
5010 
5011     if (pkey == NULL)
5012         /* Solaris Kerberos */
5013         return EINVAL;
5014 
5015     if ((md_ctx = EVP_MD_CTX_new()) == NULL)
5016         return EINVAL;
5017 
5018     EVP_VerifyInit(md_ctx, EVP_sha1());
5019     EVP_SignUpdate(md_ctx, data, data_len);
5020     *sig_len = EVP_PKEY_size(pkey);
5021     if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
5022         goto cleanup;
5023     EVP_SignFinal(md_ctx, *sig, sig_len, pkey);
5024 
5025     retval = 0;
5026 
5027   cleanup:
5028     EVP_MD_CTX_free(md_ctx);
5029 
5030     return retval;
5031 }
5032 
5033 /*
5034  * Note:
5035  * This is not the routine the KDC uses to get its certificate.
5036  * This routine is intended to be called by the client
5037  * to obtain the KDC's certificate from some local storage
5038  * to be sent as a hint in its request to the KDC.
5039  */
5040 /* ARGSUSED */
5041 krb5_error_code
5042 pkinit_get_kdc_cert(krb5_context context,
5043                     pkinit_plg_crypto_context plg_cryptoctx,
5044                     pkinit_req_crypto_context req_cryptoctx,
5045                     pkinit_identity_crypto_context id_cryptoctx,
5046                     krb5_principal princ)
5047 {
5048    /* Solaris Kerberos */


6294         krb5_cas[i]->subjectName.length = 0;
6295         krb5_cas[i]->subjectName.data = NULL;
6296 
6297         xn = X509_get_subject_name(x);
6298         len = i2d_X509_NAME(xn, NULL);
6299         if ((p = krb5_cas[i]->subjectName.data = (unsigned char *)malloc((size_t) len)) == NULL)
6300             goto cleanup;
6301         i2d_X509_NAME(xn, &p);
6302         krb5_cas[i]->subjectName.length = len;
6303 
6304         /* fill-in issuerAndSerialNumber */
6305         krb5_cas[i]->issuerAndSerialNumber.length = 0;
6306         krb5_cas[i]->issuerAndSerialNumber.magic = 0;
6307         krb5_cas[i]->issuerAndSerialNumber.data = NULL;
6308 
6309 #ifdef LONGHORN_BETA_COMPAT
6310 if (longhorn == 0) { /* XXX Longhorn doesn't like this */
6311 #endif
6312         is = PKCS7_ISSUER_AND_SERIAL_new();
6313         X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6314         ASN1_INTEGER_free(is->serial);
6315         is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
6316         len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6317         if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
6318              (unsigned char *)malloc((size_t) len)) == NULL)
6319             goto cleanup;
6320         i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6321         krb5_cas[i]->issuerAndSerialNumber.length = len;
6322 #ifdef LONGHORN_BETA_COMPAT
6323 }
6324 #endif
6325 
6326         /* fill-in subjectKeyIdentifier */
6327         krb5_cas[i]->subjectKeyIdentifier.length = 0;
6328         krb5_cas[i]->subjectKeyIdentifier.magic = 0;
6329         krb5_cas[i]->subjectKeyIdentifier.data = NULL;
6330 
6331 
6332 #ifdef LONGHORN_BETA_COMPAT
6333 if (longhorn == 0) {    /* XXX Longhorn doesn't like this */
6334 #endif
6335         if (X509_get_ext_by_NID(x, NID_subject_key_identifier, -1) >= 0) {


6499                 krb5_cas[i]->choice = choice_trusted_cas_principalName;
6500                 break;
6501             case choice_trusted_cas_caName:
6502                 krb5_cas[i]->choice = choice_trusted_cas_caName;
6503                 krb5_cas[i]->u.caName.data = NULL;
6504                 krb5_cas[i]->u.caName.length = 0;
6505                 xn = X509_get_subject_name(x);
6506                 len = i2d_X509_NAME(xn, NULL);
6507                 if ((p = krb5_cas[i]->u.caName.data =
6508                     (unsigned char *)malloc((size_t) len)) == NULL)
6509                     goto cleanup;
6510                 i2d_X509_NAME(xn, &p);
6511                 krb5_cas[i]->u.caName.length = len;
6512                 break;
6513             case choice_trusted_cas_issuerAndSerial:
6514                 krb5_cas[i]->choice = choice_trusted_cas_issuerAndSerial;
6515                 krb5_cas[i]->u.issuerAndSerial.data = NULL;
6516                 krb5_cas[i]->u.issuerAndSerial.length = 0;
6517                 is = PKCS7_ISSUER_AND_SERIAL_new();
6518                 X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
6519                 ASN1_INTEGER_free(is->serial);
6520                 is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
6521                 len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6522                 if ((p = krb5_cas[i]->u.issuerAndSerial.data =
6523                     (unsigned char *)malloc((size_t) len)) == NULL)
6524                     goto cleanup;
6525                 i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6526                 krb5_cas[i]->u.issuerAndSerial.length = len;
6527                 if (is != NULL) {
6528                     if (is->issuer != NULL)
6529                         X509_NAME_free(is->issuer);
6530                     if (is->serial != NULL)
6531                         ASN1_INTEGER_free(is->serial);
6532                     free(is);
6533                 }
6534                 break;
6535             default: break;
6536         }
6537     }
6538     retval = 0;
6539     *ids = krb5_cas;
6540 cleanup:


6549 create_issuerAndSerial(krb5_context context,
6550                        pkinit_plg_crypto_context plg_cryptoctx,
6551                        pkinit_req_crypto_context req_cryptoctx,
6552                        pkinit_identity_crypto_context id_cryptoctx,
6553                        unsigned char **out,
6554                        unsigned int *out_len)
6555 {
6556     unsigned char *p = NULL;
6557     PKCS7_ISSUER_AND_SERIAL *is = NULL;
6558     int len = 0;
6559     krb5_error_code retval = ENOMEM;
6560     X509 *cert = req_cryptoctx->received_cert;
6561 
6562     *out = NULL;
6563     *out_len = 0;
6564     if (req_cryptoctx->received_cert == NULL)
6565         return 0;
6566 
6567     is = PKCS7_ISSUER_AND_SERIAL_new();
6568     X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
6569     ASN1_INTEGER_free(is->serial);
6570     is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert));
6571     len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
6572     if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
6573         goto cleanup;
6574     i2d_PKCS7_ISSUER_AND_SERIAL(is, &p);
6575     *out_len = len;
6576     retval = 0;
6577 
6578 cleanup:
6579     X509_NAME_free(is->issuer);
6580     ASN1_INTEGER_free(is->serial);
6581     free(is);
6582 
6583     return retval;
6584 }
6585 
6586 static int
6587 pkcs7_decrypt(krb5_context context,
6588               pkinit_identity_crypto_context id_cryptoctx,
6589               PKCS7 *p7,
6590               BIO *data)


6735     xalg=p7->d.enveloped->enc_data->algorithm;
6736 #endif
6737 
6738     if ((etmp=BIO_new(BIO_f_cipher())) == NULL) {
6739         PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
6740         goto cleanup;
6741     }
6742 
6743     /* It was encrypted, we need to decrypt the secret key
6744      * with the private key */
6745 
6746     /* Find the recipientInfo which matches the passed certificate
6747      * (if any)
6748      */
6749 
6750     if (cert) {
6751         for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6752             int tmp_ret = 0;
6753             ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6754             tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
6755                 X509_get_issuer_name(cert));
6756             if (!tmp_ret) {
6757                 tmp_ret = ASN1_INTEGER_cmp(X509_get_serialNumber(cert),
6758                                              ri->issuer_and_serial->serial);
6759                 if (!tmp_ret)
6760                     break;
6761             }
6762             ri=NULL;
6763         }
6764         if (ri == NULL) {
6765             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6766                      PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6767             goto cleanup;
6768         }
6769         
6770     }
6771 
6772     /* If we haven't got a certificate try each ri in turn */
6773 
6774     if (cert == NULL) {
6775         for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
6776             ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
6777             jj = pkinit_decode_data(context, id_cryptoctx,
6778                 (unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
6779                 ASN1_STRING_length(ri->enc_key),
6780                 &tmp, &tmp_len);
6781             if (jj) {
6782                 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6783                 goto cleanup;
6784             }
6785 
6786             if (!jj && tmp_len > 0) {
6787                 jj = tmp_len;
6788                 break;
6789             }
6790 
6791             ERR_clear_error();
6792             ri = NULL;
6793         }
6794 
6795         if (ri == NULL) {
6796             PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
6797             goto cleanup;
6798         }
6799     }
6800     else {
6801         jj = pkinit_decode_data(context, id_cryptoctx,
6802             (unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
6803             ASN1_STRING_length(ri->enc_key),
6804             &tmp, &tmp_len);
6805         /* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
6806         if (jj || tmp_len == 0) {
6807             PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
6808             goto cleanup;
6809         }
6810         jj = tmp_len;
6811     }
6812 
6813     evp_ctx=NULL;
6814     BIO_get_cipher_ctx(etmp,&evp_ctx);
6815     if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
6816         goto cleanup;
6817     if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
6818         goto cleanup;
6819 
6820     if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
6821         /* Some S/MIME clients don't use the same key
6822          * and effective key length. The key length is
6823          * determined by the size of the decrypted RSA key.
6824          */
6825         if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
6826             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
6827                      PKCS7_R_DECRYPT_ERROR);
6828             goto cleanup;
6829         }
6830     }
6831     if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
6832         goto cleanup;
6833 
6834     OPENSSL_cleanse(tmp,jj);
6835 
6836     if (out == NULL)
6837         out=etmp;
6838     else
6839         BIO_push(out,etmp);
6840     etmp=NULL;
6841 
6842     if (data_body->length > 0)
6843         bio = BIO_new_mem_buf(data_body->data, data_body->length);
6844     else {
6845         bio=BIO_new(BIO_s_mem());
6846         BIO_set_mem_eof_return(bio,0);
6847     }