Print this page
6429 SMB domain join doesn't work with libreSSL


  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));
 392 
 393     pkiDebug("%s: initializing openssl crypto context at %p\n",
 394              __FUNCTION__, ctx);
 395     retval = pkinit_init_pkinit_oids(ctx);


 490 }
 491 
 492 void
 493 pkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx)
 494 {
 495     if (req_cryptoctx == NULL)
 496         return;
 497 
 498     pkiDebug("%s: freeing   ctx at %p\n", __FUNCTION__, req_cryptoctx);
 499     if (req_cryptoctx->dh != NULL)
 500       DH_free(req_cryptoctx->dh);
 501     if (req_cryptoctx->received_cert != NULL)
 502       X509_free(req_cryptoctx->received_cert);
 503 
 504     free(req_cryptoctx);
 505 }
 506 
 507 static krb5_error_code
 508 pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx)
 509 {
 510     krb5_error_code retval = ENOMEM;
 511     int nid = 0;

 512 
 513     /*
 514      * If OpenSSL already knows about the OID, use the
 515      * existing definition. Otherwise, create an OID object.
 516      */
 517     #define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln) \
 518         nid = OBJ_txt2nid(oid); \
 519         if (nid == NID_undef) { \
 520             nid = OBJ_create(oid, sn, ln); \
 521             if (nid == NID_undef) { \
 522                 pkiDebug("Error creating oid object for '%s'\n", oid); \
 523                 goto out; \
 524             } \
 525         } \
 526         ctx->vn = OBJ_nid2obj(nid);
 527     
 528     /* Solaris Kerberos */
 529     retval = k5_mutex_lock(&oids_mutex);
 530     if (retval != 0)
 531         goto out;
 532 
 533     CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san,
 534                          "id-pkinit-san", "KRB5PrincipalName");

 535 
 536     CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData,
 537                          "id-pkinit-authdata", "PKINIT signedAuthPack");

 538 
 539     CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData,
 540                          "id-pkinit-DHKeyData", "PKINIT dhSignedData");

 541 
 542     CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData,
 543                          "id-pkinit-rkeyData", "PKINIT encKeyPack");

 544 
 545     CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth,
 546                          "id-pkinit-KPClientAuth", "PKINIT Client EKU");

 547 
 548     CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc,
 549                          "id-pkinit-KPKdc", "KDC EKU");

 550 
 551 #if 0
 552     CREATE_OBJ_IF_NEEDED("1.2.840.113549.1.7.1", id_pkinit_authData9,
 553                          "id-pkcs7-data", "PKCS7 data");
 554 #else
 555     /* See note in pkinit_pkcs7type2oid() */
 556     ctx->id_pkinit_authData9 = NULL;
 557 #endif
 558 
 559     CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.2", id_ms_kp_sc_logon,
 560                          "id-ms-kp-sc-logon EKU", "Microsoft SmartCard Login EKU");
 561 
 562     CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn,
 563                          "id-ms-san-upn", "Microsoft Universal Principal Name");
 564 
 565     CREATE_OBJ_IF_NEEDED("1.3.6.1.5.5.7.3.1", id_kp_serverAuth,
 566                          "id-kp-serverAuth EKU", "Server Authentication EKU");
 567 
 568     /* Success */
 569     retval = 0;
 570     
 571     pkinit_oids_refs++;
 572     /* Solaris Kerberos */
 573     k5_mutex_unlock(&oids_mutex);
 574 
 575 out:
 576     return retval;
 577 }
 578 
 579 static krb5_error_code
 580 get_cert(char *filename, X509 **retcert)
 581 {
 582     X509 *cert = NULL;
 583     BIO *tmp = NULL;
 584     int code;
 585     krb5_error_code retval;
 586 
 587     if (filename == NULL || retcert == NULL)
 588         return EINVAL;
 589 
 590     *retcert = NULL;
 591 
 592     tmp = BIO_new(BIO_s_file());
 593     if (tmp == NULL)
 594         return ENOMEM;
 595 
 596     code = BIO_read_filename(tmp, filename);


 635     }
 636     pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL);
 637     if (pkey == NULL) {
 638         retval = EIO;
 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)


 819     if (ctx->cert_label != NULL)
 820         free(ctx->cert_label);
 821     if (ctx->PIN != NULL) {
 822         (void) memset(ctx->PIN, 0, strlen(ctx->PIN));
 823         free(ctx->PIN);
 824     }
 825 #endif
 826 }
 827 
 828 krb5_error_code
 829 pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx,
 830                              krb5_prompter_fct prompter,
 831                              void *prompter_data)
 832 {
 833     id_cryptoctx->prompter = prompter;
 834     id_cryptoctx->prompter_data = prompter_data;
 835 
 836     return 0;
 837 }
 838 

















































 839 /* ARGSUSED */
 840 krb5_error_code
 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;
 882 
 883     /* start creating PKCS7 data */
 884     if ((p7 = PKCS7_new()) == NULL)
 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 */


 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) {


1077     if (cms_msg_type != CMS_SIGN_DRAFT9) 
1078         free(abuf);
1079     if (retval)
1080         goto cleanup2;
1081 
1082     /* Add signature */
1083     if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
1084                          (int)sig_len)) {
1085         unsigned long err = ERR_peek_error();
1086         retval = KRB5KDC_ERR_PREAUTH_FAILED;
1087         krb5_set_error_message(context, retval, "%s\n",
1088                                ERR_error_string(err, NULL));
1089         pkiDebug("failed to add a signed digest attribute\n");
1090         goto cleanup2;
1091     }
1092     /* adder signer_info to pkcs7 signed */
1093     if (!PKCS7_add_signer(p7, p7si))
1094         goto cleanup2;
1095 
1096     /* start on adding data to the pkcs7 signed */
1097     if ((inner_p7 = PKCS7_new()) == NULL)
1098         goto cleanup2;
1099     if ((pkinit_data = ASN1_TYPE_new()) == NULL)
1100         goto cleanup2;
1101     pkinit_data->type = V_ASN1_OCTET_STRING;
1102     if ((pkinit_data->value.octet_string = ASN1_OCTET_STRING_new()) == NULL)
1103         goto cleanup2;
1104     if (!ASN1_OCTET_STRING_set(pkinit_data->value.octet_string, data,
1105                                (int)data_len)) {
1106         unsigned long err = ERR_peek_error();
1107         retval = KRB5KDC_ERR_PREAUTH_FAILED;
1108         krb5_set_error_message(context, retval, "%s\n",
1109                                ERR_error_string(err, NULL));
1110         pkiDebug("failed to add pkcs7 data\n");
1111         goto cleanup2;
1112     }
1113 
1114     if (!PKCS7_set0_type_other(inner_p7, OBJ_obj2nid(oid), pkinit_data))
1115         goto cleanup2;
1116 
1117     if (p7s->contents != NULL)
1118         PKCS7_free(p7s->contents);
1119     p7s->contents = inner_p7;
1120 
1121     *signed_data_len = i2d_PKCS7(p7, NULL);
1122     if (!(*signed_data_len)) {
1123         unsigned long err = ERR_peek_error();
1124         retval = KRB5KDC_ERR_PREAUTH_FAILED;
1125         krb5_set_error_message(context, retval, "%s\n",
1126                                ERR_error_string(err, NULL));
1127         pkiDebug("failed to der encode pkcs7\n");
1128         goto cleanup2;
1129     }
1130     if ((p = *signed_data =
1131          (unsigned char *) malloc((size_t)*signed_data_len)) == NULL)
1132         goto cleanup2;
1133 
1134     /* DER encode PKCS7 data */
1135     retval = i2d_PKCS7(p7, &p);
1136     if (!retval) {


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) {
1234         unsigned long err = ERR_peek_error();
1235         krb5_set_error_message(context, retval, "%s\n",
1236                                ERR_error_string(err, 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;


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.
3144              */ 
3145             if (cryptoctx->id_pkinit_authData9 == NULL) {
3146                 pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n",
3147                          __FUNCTION__);
3148                 nid = OBJ_create("1.2.840.113549.1.7.1", "id-pkcs7-data",
3149                                  "PKCS7 data");
3150                 if (nid == NID_undef)
3151                     return NULL;
3152                 cryptoctx->id_pkinit_authData9 = OBJ_nid2obj(nid);
3153             }
3154             return cryptoctx->id_pkinit_authData9;
3155         case CMS_SIGN_SERVER:
3156             return cryptoctx->id_pkinit_DHKeyData;
3157         case CMS_ENVEL_SERVER:
3158             return cryptoctx->id_pkinit_rkeyData;
3159         default:
3160             return NULL;
3161     }
3162 
3163 }
3164 
3165 #ifdef LONGHORN_BETA_COMPAT
3166 #if 0
3167 /*
3168  * This is a version that worked with Longhorn Beta 3.
3169  */
3170 static int
3171 wrap_signeddata(unsigned char *data, unsigned int data_len,
3172                 unsigned char **out, unsigned int *out_len,
3173                 int is_longhorn_server)
3174 {




  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 2017 RackTop Systems.
  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 krb5_error_code
 374 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
 375 
 376     krb5_error_code retval = ENOMEM;
 377     pkinit_plg_crypto_context ctx = NULL;
 378 
 379     /* initialize openssl routines */
 380     /* Solaris Kerberos */
 381     retval = openssl_init();
 382     if (retval != 0)
 383         goto out;
 384 
 385     ctx = (pkinit_plg_crypto_context)malloc(sizeof(*ctx));
 386     if (ctx == NULL)
 387         goto out;
 388     (void) memset(ctx, 0, sizeof(*ctx));
 389 
 390     pkiDebug("%s: initializing openssl crypto context at %p\n",
 391              __FUNCTION__, ctx);
 392     retval = pkinit_init_pkinit_oids(ctx);


 487 }
 488 
 489 void
 490 pkinit_fini_req_crypto(pkinit_req_crypto_context req_cryptoctx)
 491 {
 492     if (req_cryptoctx == NULL)
 493         return;
 494 
 495     pkiDebug("%s: freeing   ctx at %p\n", __FUNCTION__, req_cryptoctx);
 496     if (req_cryptoctx->dh != NULL)
 497       DH_free(req_cryptoctx->dh);
 498     if (req_cryptoctx->received_cert != NULL)
 499       X509_free(req_cryptoctx->received_cert);
 500 
 501     free(req_cryptoctx);
 502 }
 503 
 504 static krb5_error_code
 505 pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx)
 506 {
 507     ctx->id_pkinit_san = OBJ_txt2obj("1.3.6.1.5.2.2", 1);
 508     if (ctx->id_pkinit_san == NULL)
 509         return ENOMEM;
 510 
 511     ctx->id_pkinit_authData = OBJ_txt2obj("1.3.6.1.5.2.3.1", 1);
 512     if (ctx->id_pkinit_authData == NULL)
 513         return ENOMEM;











 514 
 515     ctx->id_pkinit_DHKeyData = OBJ_txt2obj("1.3.6.1.5.2.3.2", 1);
 516     if (ctx->id_pkinit_DHKeyData == NULL)
 517         return ENOMEM;

 518 
 519     ctx->id_pkinit_rkeyData = OBJ_txt2obj("1.3.6.1.5.2.3.3", 1);
 520     if (ctx->id_pkinit_rkeyData == NULL)
 521         return ENOMEM;
 522 
 523     ctx->id_pkinit_KPClientAuth = OBJ_txt2obj("1.3.6.1.5.2.3.4", 1);
 524     if (ctx->id_pkinit_KPClientAuth == NULL)
 525         return ENOMEM;
 526 
 527     ctx->id_pkinit_KPKdc = OBJ_txt2obj("1.3.6.1.5.2.3.5", 1);
 528     if (ctx->id_pkinit_KPKdc == NULL)
 529         return ENOMEM;
 530 
 531     ctx->id_ms_kp_sc_logon = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.2", 1);
 532     if (ctx->id_ms_kp_sc_logon == NULL)
 533         return ENOMEM;
 534 
 535     ctx->id_ms_san_upn = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1);
 536     if (ctx->id_ms_san_upn == NULL)
 537         return ENOMEM;
 538 
 539     ctx->id_kp_serverAuth = OBJ_txt2obj("1.3.6.1.5.5.7.3.1", 1);
 540     if (ctx->id_kp_serverAuth == NULL)
 541         return ENOMEM;
 542 
 543     return 0;

























 544 }
 545 
 546 static krb5_error_code
 547 get_cert(char *filename, X509 **retcert)
 548 {
 549     X509 *cert = NULL;
 550     BIO *tmp = NULL;
 551     int code;
 552     krb5_error_code retval;
 553 
 554     if (filename == NULL || retcert == NULL)
 555         return EINVAL;
 556 
 557     *retcert = NULL;
 558 
 559     tmp = BIO_new(BIO_s_file());
 560     if (tmp == NULL)
 561         return ENOMEM;
 562 
 563     code = BIO_read_filename(tmp, filename);


 602     }
 603     pkey = (EVP_PKEY *) PEM_read_bio_PrivateKey(tmp, NULL, NULL, NULL);
 604     if (pkey == NULL) {
 605         retval = EIO;
 606         pkiDebug("failed to read private key from %s\n", filename);
 607         goto cleanup;
 608     }
 609     *retkey = pkey;
 610     retval = 0;
 611 cleanup:
 612     if (tmp != NULL)
 613         BIO_free(tmp);
 614     return retval;
 615 }
 616 
 617 static void
 618 pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
 619 {
 620     if (ctx == NULL)
 621         return;
 622     ASN1_OBJECT_free(ctx->id_pkinit_san);
 623     ASN1_OBJECT_free(ctx->id_pkinit_authData);
 624     ASN1_OBJECT_free(ctx->id_pkinit_DHKeyData);
 625     ASN1_OBJECT_free(ctx->id_pkinit_rkeyData);
 626     ASN1_OBJECT_free(ctx->id_pkinit_KPClientAuth);
 627     ASN1_OBJECT_free(ctx->id_pkinit_KPKdc);
 628     ASN1_OBJECT_free(ctx->id_ms_kp_sc_logon);
 629     ASN1_OBJECT_free(ctx->id_ms_san_upn);
 630     ASN1_OBJECT_free(ctx->id_kp_serverAuth);
 631 }
 632 
 633 static krb5_error_code
 634 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
 635 {
 636     krb5_error_code retval = ENOMEM;
 637 
 638     plgctx->dh_1024 = DH_new();
 639     if (plgctx->dh_1024 == NULL)
 640         goto cleanup;
 641     plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
 642         sizeof(pkinit_1024_dhprime), NULL);
 643     if ((plgctx->dh_1024->g = BN_new()) == NULL ||
 644         (plgctx->dh_1024->q = BN_new()) == NULL)
 645         goto cleanup;
 646     BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
 647     BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
 648 
 649     plgctx->dh_2048 = DH_new();
 650     if (plgctx->dh_2048 == NULL)


 788     if (ctx->cert_label != NULL)
 789         free(ctx->cert_label);
 790     if (ctx->PIN != NULL) {
 791         (void) memset(ctx->PIN, 0, strlen(ctx->PIN));
 792         free(ctx->PIN);
 793     }
 794 #endif
 795 }
 796 
 797 krb5_error_code
 798 pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx,
 799                              krb5_prompter_fct prompter,
 800                              void *prompter_data)
 801 {
 802     id_cryptoctx->prompter = prompter;
 803     id_cryptoctx->prompter_data = prompter_data;
 804 
 805     return 0;
 806 }
 807 
 808 /* Create a CMS ContentInfo of type oid containing the octet string in data. */
 809 static krb5_error_code
 810 create_contentinfo(krb5_context context,
 811                    ASN1_OBJECT *oid,
 812                    unsigned char *data,
 813                    size_t data_len,
 814                    PKCS7 **p7_out)
 815 {
 816     PKCS7 *p7 = NULL;
 817     ASN1_OCTET_STRING *ostr = NULL;
 818 
 819     *p7_out = NULL;
 820 
 821     ostr = ASN1_OCTET_STRING_new();
 822     if (ostr == NULL)
 823         goto oom;
 824     if (!ASN1_OCTET_STRING_set(ostr, (unsigned char *)data, data_len))
 825         goto oom;
 826 
 827     p7 = PKCS7_new();
 828     if (p7 == NULL)
 829         goto oom;
 830     p7->type = OBJ_dup(oid);
 831     if (p7->type == NULL)
 832         goto oom;
 833 
 834     if (OBJ_obj2nid(oid) == NID_pkcs7_data) {
 835         /* Draft 9 uses id-pkcs7-data for signed data.  For this type OpenSSL
 836          * expects an octet string in d.data. */
 837         p7->d.data = ostr;
 838     } else {
 839         p7->d.other = ASN1_TYPE_new();
 840         if (p7->d.other == NULL)
 841             goto oom;
 842         p7->d.other->type = V_ASN1_OCTET_STRING;
 843         p7->d.other->value.octet_string = ostr;
 844     }
 845 
 846     *p7_out = p7;
 847     return 0;
 848 
 849 oom:
 850     if (ostr != NULL)
 851         ASN1_OCTET_STRING_free(ostr);
 852     if (p7 != NULL)
 853         PKCS7_free(p7);
 854     return ENOMEM;
 855 }
 856 
 857 /* ARGSUSED */
 858 krb5_error_code
 859 cms_signeddata_create(krb5_context context,
 860                       pkinit_plg_crypto_context plg_cryptoctx,
 861                       pkinit_req_crypto_context req_cryptoctx,
 862                       pkinit_identity_crypto_context id_cryptoctx,
 863                       int cms_msg_type,
 864                       int include_certchain,
 865                       unsigned char *data,
 866                       unsigned int data_len,
 867                       unsigned char **signed_data,
 868                       unsigned int *signed_data_len)
 869 {
 870     /* Solaris Kerberos */
 871     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
 872     PKCS7  *p7 = NULL, *inner_p7 = NULL;
 873     PKCS7_SIGNED *p7s = NULL;
 874     PKCS7_SIGNER_INFO *p7si = NULL;
 875     unsigned char *p;

 876     STACK_OF(X509) * cert_stack = NULL;
 877     ASN1_OCTET_STRING *digest_attr = NULL;
 878     EVP_MD_CTX ctx, ctx2;
 879     const EVP_MD *md_tmp = NULL;
 880     unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
 881     unsigned char *digestInfo_buf = NULL, *abuf = NULL;
 882     unsigned int md_len, md_len2, alen, digestInfo_len;
 883     STACK_OF(X509_ATTRIBUTE) * sk;
 884     unsigned char *sig = NULL;
 885     unsigned int sig_len = 0;
 886     X509_ALGOR *alg = NULL;
 887     ASN1_OCTET_STRING *digest = NULL;
 888     unsigned int alg_len = 0, digest_len = 0;
 889     unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
 890     X509 *cert = NULL;
 891     ASN1_OBJECT *oid = NULL, *oid_copy;
 892 
 893     /* Solaris Kerberos */
 894     if (signed_data == NULL)
 895         return EINVAL;
 896 
 897     if (signed_data_len == NULL)
 898         return EINVAL;
 899 
 900     /* start creating PKCS7 data */
 901     if ((p7 = PKCS7_new()) == NULL)
 902         goto cleanup;
 903     p7->type = OBJ_nid2obj(NID_pkcs7_signed);
 904 
 905     if ((p7s = PKCS7_SIGNED_new()) == NULL)
 906         goto cleanup;
 907     p7->d.sign = p7s;
 908     if (!ASN1_INTEGER_set(p7s->version, 3))
 909         goto cleanup;
 910 
 911     /* create a cert chain that has at least the signer's certificate */


 996     if (cms_msg_type == CMS_SIGN_DRAFT9) {
 997         /* don't include signed attributes for pa-type 15 request */
 998         abuf = data;
 999         alen = data_len;
1000     } else {
1001         /* add signed attributes */
1002         /* compute sha1 digest over the EncapsulatedContentInfo */
1003         EVP_MD_CTX_init(&ctx);
1004         EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
1005         EVP_DigestUpdate(&ctx, data, data_len);
1006         md_tmp = EVP_MD_CTX_md(&ctx);
1007         EVP_DigestFinal_ex(&ctx, md_data, &md_len);
1008 
1009         /* create a message digest attr */
1010         digest_attr = ASN1_OCTET_STRING_new();
1011         ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
1012         PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
1013                                    V_ASN1_OCTET_STRING, (char *) digest_attr);
1014 
1015         /* create a content-type attr */
1016         oid_copy = OBJ_dup(oid);
1017         if (oid_copy == NULL)
1018                 goto cleanup2;
1019         PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, 
1020                                    V_ASN1_OBJECT, oid_copy);
1021 
1022         /* create the signature over signed attributes. get DER encoded value */
1023         /* This is the place where smartcard signature needs to be calculated */
1024         sk = p7si->auth_attr;
1025         alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
1026                              ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
1027         if (abuf == NULL)
1028             goto cleanup2;
1029     }
1030 
1031 #ifndef WITHOUT_PKCS11
1032     /* Some tokens can only do RSAEncryption without sha1 hash */
1033     /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
1034      * function and the hash value into an ASN.1 value of type DigestInfo
1035      * DigestInfo::=SEQUENCE {
1036      *  digestAlgorithm  AlgorithmIdentifier,
1037      *  digest OCTET STRING }
1038      */
1039     if (id_cryptoctx->pkcs11_method == 1 && 
1040             id_cryptoctx->mech == CKM_RSA_PKCS) {


1097     if (cms_msg_type != CMS_SIGN_DRAFT9) 
1098         free(abuf);
1099     if (retval)
1100         goto cleanup2;
1101 
1102     /* Add signature */
1103     if (!ASN1_STRING_set(p7si->enc_digest, (unsigned char *) sig,
1104                          (int)sig_len)) {
1105         unsigned long err = ERR_peek_error();
1106         retval = KRB5KDC_ERR_PREAUTH_FAILED;
1107         krb5_set_error_message(context, retval, "%s\n",
1108                                ERR_error_string(err, NULL));
1109         pkiDebug("failed to add a signed digest attribute\n");
1110         goto cleanup2;
1111     }
1112     /* adder signer_info to pkcs7 signed */
1113     if (!PKCS7_add_signer(p7, p7si))
1114         goto cleanup2;
1115 
1116     /* start on adding data to the pkcs7 signed */
1117     retval = create_contentinfo(context, oid, data, data_len, &inner_p7);



















1118     if (p7s->contents != NULL)
1119         PKCS7_free(p7s->contents);
1120     p7s->contents = inner_p7;
1121 
1122     *signed_data_len = i2d_PKCS7(p7, NULL);
1123     if (!(*signed_data_len)) {
1124         unsigned long err = ERR_peek_error();
1125         retval = KRB5KDC_ERR_PREAUTH_FAILED;
1126         krb5_set_error_message(context, retval, "%s\n",
1127                                ERR_error_string(err, NULL));
1128         pkiDebug("failed to der encode pkcs7\n");
1129         goto cleanup2;
1130     }
1131     if ((p = *signed_data =
1132          (unsigned char *) malloc((size_t)*signed_data_len)) == NULL)
1133         goto cleanup2;
1134 
1135     /* DER encode PKCS7 data */
1136     retval = i2d_PKCS7(p7, &p);
1137     if (!retval) {


1208     unsigned int vflags = 0, size = 0;
1209     const unsigned char *p = signed_data;
1210     STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
1211     PKCS7_SIGNER_INFO *si = NULL;
1212     X509 *x = NULL;
1213     X509_STORE *store = NULL;
1214     X509_STORE_CTX cert_ctx;
1215     STACK_OF(X509) *intermediateCAs = NULL;
1216     STACK_OF(X509_CRL) *revoked = NULL;
1217     STACK_OF(X509) *verified_chain = NULL;
1218     ASN1_OBJECT *oid = NULL;
1219     krb5_external_principal_identifier **krb5_verified_chain = NULL;
1220     krb5_data *authz = NULL;
1221     char buf[DN_BUF_LEN];
1222 
1223 #ifdef DEBUG_ASN1
1224     print_buffer_bin(signed_data, signed_data_len,
1225                      "/tmp/client_received_pkcs7_signeddata");
1226 #endif
1227 

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) {
1234         unsigned long err = ERR_peek_error();
1235         krb5_set_error_message(context, retval, "%s\n",
1236                                ERR_error_string(err, 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;


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     switch (pkcs7_type) {
3131         case CMS_SIGN_CLIENT:
3132             return cryptoctx->id_pkinit_authData;
3133         case CMS_SIGN_DRAFT9:
3134             return OBJ_nid2obj(NID_pkcs7_data);


















3135         case CMS_SIGN_SERVER:
3136             return cryptoctx->id_pkinit_DHKeyData;
3137         case CMS_ENVEL_SERVER:
3138             return cryptoctx->id_pkinit_rkeyData;
3139         default:
3140             return NULL;
3141     }
3142 
3143 }
3144 
3145 #ifdef LONGHORN_BETA_COMPAT
3146 #if 0
3147 /*
3148  * This is a version that worked with Longhorn Beta 3.
3149  */
3150 static int
3151 wrap_signeddata(unsigned char *data, unsigned int data_len,
3152                 unsigned char **out, unsigned int *out_len,
3153                 int is_longhorn_server)
3154 {