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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c
          +++ new/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c
↓ open down ↓ 23 lines elided ↑ open up ↑
  24   24   * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
  25   25   * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
  26   26   * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
  27   27   * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
  28   28   * SUCH DAMAGES.
  29   29   */
  30   30  
  31   31  /*
  32   32   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  33   33   * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
       34 + * Copyright 2017 RackTop Systems.
  34   35   */
  35   36  
  36   37  #include <errno.h>
  37   38  #include <string.h>
  38   39  #include <stdio.h>
  39   40  #include <stdlib.h>
  40   41  #include <dlfcn.h>
  41   42  #include <unistd.h>
  42   43  #include <dirent.h>
  43   44  
↓ open down ↓ 318 lines elided ↑ open up ↑
 362  363      0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
 363  364      0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
 364  365      0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
 365  366      0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
 366  367      0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
 367  368      0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
 368  369      0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
 369  370      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 370  371  };
 371  372  
 372      -/* Solaris Kerberos */
 373      -static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
 374      -static int pkinit_oids_refs = 0;
 375      -
 376  373  krb5_error_code
 377  374  pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) {
 378  375  
 379  376      krb5_error_code retval = ENOMEM;
 380  377      pkinit_plg_crypto_context ctx = NULL;
 381  378  
 382  379      /* initialize openssl routines */
 383  380      /* Solaris Kerberos */
 384  381      retval = openssl_init();
 385  382      if (retval != 0)
↓ open down ↓ 114 lines elided ↑ open up ↑
 500  497        DH_free(req_cryptoctx->dh);
 501  498      if (req_cryptoctx->received_cert != NULL)
 502  499        X509_free(req_cryptoctx->received_cert);
 503  500  
 504  501      free(req_cryptoctx);
 505  502  }
 506  503  
 507  504  static krb5_error_code
 508  505  pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx)
 509  506  {
 510      -    krb5_error_code retval = ENOMEM;
 511      -    int nid = 0;
      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;
 512  510  
 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;
      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;
 532  514  
 533      -    CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san,
 534      -                         "id-pkinit-san", "KRB5PrincipalName");
      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;
 535  518  
 536      -    CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData,
 537      -                         "id-pkinit-authdata", "PKINIT signedAuthPack");
      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;
 538  522  
 539      -    CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData,
 540      -                         "id-pkinit-DHKeyData", "PKINIT dhSignedData");
      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;
 541  526  
 542      -    CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData,
 543      -                         "id-pkinit-rkeyData", "PKINIT encKeyPack");
      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;
 544  530  
 545      -    CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth,
 546      -                         "id-pkinit-KPClientAuth", "PKINIT Client EKU");
      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;
 547  534  
 548      -    CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc,
 549      -                         "id-pkinit-KPKdc", "KDC EKU");
      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;
 550  538  
 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
      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;
 558  542  
 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;
      543 +    return 0;
 577  544  }
 578  545  
 579  546  static krb5_error_code
 580  547  get_cert(char *filename, X509 **retcert)
 581  548  {
 582  549      X509 *cert = NULL;
 583  550      BIO *tmp = NULL;
 584  551      int code;
 585  552      krb5_error_code retval;
 586  553  
↓ open down ↓ 58 lines elided ↑ open up ↑
 645  612      if (tmp != NULL)
 646  613          BIO_free(tmp);
 647  614      return retval;
 648  615  }
 649  616  
 650  617  static void
 651  618  pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
 652  619  {
 653  620      if (ctx == NULL)
 654  621          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);
      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);
 662  631  }
 663  632  
 664  633  static krb5_error_code
 665  634  pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
 666  635  {
 667  636      krb5_error_code retval = ENOMEM;
 668  637  
 669  638      plgctx->dh_1024 = DH_new();
 670  639      if (plgctx->dh_1024 == NULL)
 671  640          goto cleanup;
↓ open down ↓ 157 lines elided ↑ open up ↑
 829  798  pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx,
 830  799                               krb5_prompter_fct prompter,
 831  800                               void *prompter_data)
 832  801  {
 833  802      id_cryptoctx->prompter = prompter;
 834  803      id_cryptoctx->prompter_data = prompter_data;
 835  804  
 836  805      return 0;
 837  806  }
 838  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 +
 839  857  /* ARGSUSED */
 840  858  krb5_error_code
 841  859  cms_signeddata_create(krb5_context context,
 842  860                        pkinit_plg_crypto_context plg_cryptoctx,
 843  861                        pkinit_req_crypto_context req_cryptoctx,
 844  862                        pkinit_identity_crypto_context id_cryptoctx,
 845  863                        int cms_msg_type,
 846  864                        int include_certchain,
 847  865                        unsigned char *data,
 848  866                        unsigned int data_len,
 849  867                        unsigned char **signed_data,
 850  868                        unsigned int *signed_data_len)
 851  869  {
 852  870      /* Solaris Kerberos */
 853  871      krb5_error_code retval = KRB5KRB_ERR_GENERIC;
 854  872      PKCS7  *p7 = NULL, *inner_p7 = NULL;
 855  873      PKCS7_SIGNED *p7s = NULL;
 856  874      PKCS7_SIGNER_INFO *p7si = NULL;
 857  875      unsigned char *p;
 858      -    ASN1_TYPE *pkinit_data = NULL;
 859  876      STACK_OF(X509) * cert_stack = NULL;
 860  877      ASN1_OCTET_STRING *digest_attr = NULL;
 861  878      EVP_MD_CTX ctx, ctx2;
 862  879      const EVP_MD *md_tmp = NULL;
 863  880      unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
 864  881      unsigned char *digestInfo_buf = NULL, *abuf = NULL;
 865  882      unsigned int md_len, md_len2, alen, digestInfo_len;
 866  883      STACK_OF(X509_ATTRIBUTE) * sk;
 867  884      unsigned char *sig = NULL;
 868  885      unsigned int sig_len = 0;
 869  886      X509_ALGOR *alg = NULL;
 870  887      ASN1_OCTET_STRING *digest = NULL;
 871  888      unsigned int alg_len = 0, digest_len = 0;
 872  889      unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL;
 873  890      X509 *cert = NULL;
 874      -    ASN1_OBJECT *oid = NULL;
      891 +    ASN1_OBJECT *oid = NULL, *oid_copy;
 875  892  
 876  893      /* Solaris Kerberos */
 877  894      if (signed_data == NULL)
 878  895          return EINVAL;
 879  896  
 880  897      if (signed_data_len == NULL)
 881  898          return EINVAL;
 882  899  
 883  900      /* start creating PKCS7 data */
 884  901      if ((p7 = PKCS7_new()) == NULL)
↓ open down ↓ 104 lines elided ↑ open up ↑
 989 1006          md_tmp = EVP_MD_CTX_md(&ctx);
 990 1007          EVP_DigestFinal_ex(&ctx, md_data, &md_len);
 991 1008  
 992 1009          /* create a message digest attr */
 993 1010          digest_attr = ASN1_OCTET_STRING_new();
 994 1011          ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len);
 995 1012          PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest,
 996 1013                                     V_ASN1_OCTET_STRING, (char *) digest_attr);
 997 1014  
 998 1015          /* create a content-type attr */
     1016 +        oid_copy = OBJ_dup(oid);
     1017 +        if (oid_copy == NULL)
     1018 +                goto cleanup2;
 999 1019          PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, 
1000      -                                   V_ASN1_OBJECT, oid);
     1020 +                                   V_ASN1_OBJECT, oid_copy);
1001 1021  
1002 1022          /* create the signature over signed attributes. get DER encoded value */
1003 1023          /* This is the place where smartcard signature needs to be calculated */
1004 1024          sk = p7si->auth_attr;
1005 1025          alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
1006 1026                               ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
1007 1027          if (abuf == NULL)
1008 1028              goto cleanup2;
1009 1029      }
1010 1030  
↓ open down ↓ 76 lines elided ↑ open up ↑
1087 1107          krb5_set_error_message(context, retval, "%s\n",
1088 1108                                 ERR_error_string(err, NULL));
1089 1109          pkiDebug("failed to add a signed digest attribute\n");
1090 1110          goto cleanup2;
1091 1111      }
1092 1112      /* adder signer_info to pkcs7 signed */
1093 1113      if (!PKCS7_add_signer(p7, p7si))
1094 1114          goto cleanup2;
1095 1115  
1096 1116      /* 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 +    retval = create_contentinfo(context, oid, data, data_len, &inner_p7);
1117 1118      if (p7s->contents != NULL)
1118 1119          PKCS7_free(p7s->contents);
1119 1120      p7s->contents = inner_p7;
1120 1121  
1121 1122      *signed_data_len = i2d_PKCS7(p7, NULL);
1122 1123      if (!(*signed_data_len)) {
1123 1124          unsigned long err = ERR_peek_error();
1124 1125          retval = KRB5KDC_ERR_PREAUTH_FAILED;
1125 1126          krb5_set_error_message(context, retval, "%s\n",
1126 1127                                 ERR_error_string(err, NULL));
↓ open down ↓ 90 lines elided ↑ open up ↑
1217 1218      ASN1_OBJECT *oid = NULL;
1218 1219      krb5_external_principal_identifier **krb5_verified_chain = NULL;
1219 1220      krb5_data *authz = NULL;
1220 1221      char buf[DN_BUF_LEN];
1221 1222  
1222 1223  #ifdef DEBUG_ASN1
1223 1224      print_buffer_bin(signed_data, signed_data_len,
1224 1225                       "/tmp/client_received_pkcs7_signeddata");
1225 1226  #endif
1226 1227  
1227      -    /* Do this early enough to create the shadow OID for pkcs7-data if needed */
1228 1228      oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type);
1229 1229      if (oid == NULL)
1230 1230          goto cleanup;
1231 1231  
1232 1232      /* decode received PKCS7 message */
1233 1233      if ((p7 = d2i_PKCS7(NULL, &p, (int)signed_data_len)) == NULL) {
1234 1234          unsigned long err = ERR_peek_error();
1235 1235          krb5_set_error_message(context, retval, "%s\n",
1236 1236                                 ERR_error_string(err, NULL));
1237 1237          pkiDebug("%s: failed to decode message: %s\n",
↓ open down ↓ 1882 lines elided ↑ open up ↑
3120 3120              default:
3121 3121                  return 0;
3122 3122          }
3123 3123      }
3124 3124      return ok;
3125 3125  }
3126 3126  
3127 3127  static ASN1_OBJECT *
3128 3128  pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
3129 3129  {
3130      -    int nid;
3131      -
3132 3130      switch (pkcs7_type) {
3133 3131          case CMS_SIGN_CLIENT:
3134 3132              return cryptoctx->id_pkinit_authData;
3135 3133          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;
     3134 +            return OBJ_nid2obj(NID_pkcs7_data);
3155 3135          case CMS_SIGN_SERVER:
3156 3136              return cryptoctx->id_pkinit_DHKeyData;
3157 3137          case CMS_ENVEL_SERVER:
3158 3138              return cryptoctx->id_pkinit_rkeyData;
3159 3139          default:
3160 3140              return NULL;
3161 3141      }
3162 3142  
3163 3143  }
3164 3144  
↓ open down ↓ 3581 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX