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

*** 29,38 **** --- 29,39 ---- */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2017 RackTop Systems. */ #include <errno.h> #include <string.h> #include <stdio.h>
*** 367,380 **** 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - /* Solaris Kerberos */ - static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER; - static int pkinit_oids_refs = 0; - krb5_error_code pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx) { krb5_error_code retval = ENOMEM; pkinit_plg_crypto_context ctx = NULL; --- 368,377 ----
*** 505,581 **** } static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx) { ! krb5_error_code retval = ENOMEM; ! int nid = 0; ! /* ! * If OpenSSL already knows about the OID, use the ! * existing definition. Otherwise, create an OID object. ! */ ! #define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln) \ ! nid = OBJ_txt2nid(oid); \ ! if (nid == NID_undef) { \ ! nid = OBJ_create(oid, sn, ln); \ ! if (nid == NID_undef) { \ ! pkiDebug("Error creating oid object for '%s'\n", oid); \ ! goto out; \ ! } \ ! } \ ! ctx->vn = OBJ_nid2obj(nid); ! /* Solaris Kerberos */ ! retval = k5_mutex_lock(&oids_mutex); ! if (retval != 0) ! goto out; ! CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san, ! "id-pkinit-san", "KRB5PrincipalName"); ! CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.1", id_pkinit_authData, ! "id-pkinit-authdata", "PKINIT signedAuthPack"); ! CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.2", id_pkinit_DHKeyData, ! "id-pkinit-DHKeyData", "PKINIT dhSignedData"); ! CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.3", id_pkinit_rkeyData, ! "id-pkinit-rkeyData", "PKINIT encKeyPack"); ! CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.4", id_pkinit_KPClientAuth, ! "id-pkinit-KPClientAuth", "PKINIT Client EKU"); ! CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.3.5", id_pkinit_KPKdc, ! "id-pkinit-KPKdc", "KDC EKU"); ! #if 0 ! CREATE_OBJ_IF_NEEDED("1.2.840.113549.1.7.1", id_pkinit_authData9, ! "id-pkcs7-data", "PKCS7 data"); ! #else ! /* See note in pkinit_pkcs7type2oid() */ ! ctx->id_pkinit_authData9 = NULL; ! #endif ! ! CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.2", id_ms_kp_sc_logon, ! "id-ms-kp-sc-logon EKU", "Microsoft SmartCard Login EKU"); ! ! CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn, ! "id-ms-san-upn", "Microsoft Universal Principal Name"); ! ! CREATE_OBJ_IF_NEEDED("1.3.6.1.5.5.7.3.1", id_kp_serverAuth, ! "id-kp-serverAuth EKU", "Server Authentication EKU"); ! ! /* Success */ ! retval = 0; ! ! pkinit_oids_refs++; ! /* Solaris Kerberos */ ! k5_mutex_unlock(&oids_mutex); ! ! out: ! return retval; } static krb5_error_code get_cert(char *filename, X509 **retcert) { --- 502,548 ---- } static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context ctx) { ! ctx->id_pkinit_san = OBJ_txt2obj("1.3.6.1.5.2.2", 1); ! if (ctx->id_pkinit_san == NULL) ! return ENOMEM; ! ctx->id_pkinit_authData = OBJ_txt2obj("1.3.6.1.5.2.3.1", 1); ! if (ctx->id_pkinit_authData == NULL) ! return ENOMEM; ! ctx->id_pkinit_DHKeyData = OBJ_txt2obj("1.3.6.1.5.2.3.2", 1); ! if (ctx->id_pkinit_DHKeyData == NULL) ! return ENOMEM; ! ctx->id_pkinit_rkeyData = OBJ_txt2obj("1.3.6.1.5.2.3.3", 1); ! if (ctx->id_pkinit_rkeyData == NULL) ! return ENOMEM; ! ctx->id_pkinit_KPClientAuth = OBJ_txt2obj("1.3.6.1.5.2.3.4", 1); ! if (ctx->id_pkinit_KPClientAuth == NULL) ! return ENOMEM; ! ctx->id_pkinit_KPKdc = OBJ_txt2obj("1.3.6.1.5.2.3.5", 1); ! if (ctx->id_pkinit_KPKdc == NULL) ! return ENOMEM; ! ctx->id_ms_kp_sc_logon = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.2", 1); ! if (ctx->id_ms_kp_sc_logon == NULL) ! return ENOMEM; ! ctx->id_ms_san_upn = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1); ! if (ctx->id_ms_san_upn == NULL) ! return ENOMEM; ! ctx->id_kp_serverAuth = OBJ_txt2obj("1.3.6.1.5.5.7.3.1", 1); ! if (ctx->id_kp_serverAuth == NULL) ! return ENOMEM; ! return 0; } static krb5_error_code get_cert(char *filename, X509 **retcert) {
*** 650,666 **** static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx) { if (ctx == NULL) return; ! ! /* Only call OBJ_cleanup once! */ ! /* Solaris Kerberos: locking */ ! k5_mutex_lock(&oids_mutex); ! if (--pkinit_oids_refs == 0) ! OBJ_cleanup(); ! k5_mutex_unlock(&oids_mutex); } static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context plgctx) { --- 617,635 ---- static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx) { if (ctx == NULL) return; ! ASN1_OBJECT_free(ctx->id_pkinit_san); ! ASN1_OBJECT_free(ctx->id_pkinit_authData); ! ASN1_OBJECT_free(ctx->id_pkinit_DHKeyData); ! ASN1_OBJECT_free(ctx->id_pkinit_rkeyData); ! ASN1_OBJECT_free(ctx->id_pkinit_KPClientAuth); ! ASN1_OBJECT_free(ctx->id_pkinit_KPKdc); ! ASN1_OBJECT_free(ctx->id_ms_kp_sc_logon); ! ASN1_OBJECT_free(ctx->id_ms_san_upn); ! ASN1_OBJECT_free(ctx->id_kp_serverAuth); } static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context plgctx) {
*** 834,843 **** --- 803,861 ---- id_cryptoctx->prompter_data = prompter_data; return 0; } + /* Create a CMS ContentInfo of type oid containing the octet string in data. */ + static krb5_error_code + create_contentinfo(krb5_context context, + ASN1_OBJECT *oid, + unsigned char *data, + size_t data_len, + PKCS7 **p7_out) + { + PKCS7 *p7 = NULL; + ASN1_OCTET_STRING *ostr = NULL; + + *p7_out = NULL; + + ostr = ASN1_OCTET_STRING_new(); + if (ostr == NULL) + goto oom; + if (!ASN1_OCTET_STRING_set(ostr, (unsigned char *)data, data_len)) + goto oom; + + p7 = PKCS7_new(); + if (p7 == NULL) + goto oom; + p7->type = OBJ_dup(oid); + if (p7->type == NULL) + goto oom; + + if (OBJ_obj2nid(oid) == NID_pkcs7_data) { + /* Draft 9 uses id-pkcs7-data for signed data. For this type OpenSSL + * expects an octet string in d.data. */ + p7->d.data = ostr; + } else { + p7->d.other = ASN1_TYPE_new(); + if (p7->d.other == NULL) + goto oom; + p7->d.other->type = V_ASN1_OCTET_STRING; + p7->d.other->value.octet_string = ostr; + } + + *p7_out = p7; + return 0; + + oom: + if (ostr != NULL) + ASN1_OCTET_STRING_free(ostr); + if (p7 != NULL) + PKCS7_free(p7); + return ENOMEM; + } + /* ARGSUSED */ krb5_error_code cms_signeddata_create(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, pkinit_req_crypto_context req_cryptoctx,
*** 853,863 **** krb5_error_code retval = KRB5KRB_ERR_GENERIC; PKCS7 *p7 = NULL, *inner_p7 = NULL; PKCS7_SIGNED *p7s = NULL; PKCS7_SIGNER_INFO *p7si = NULL; unsigned char *p; - ASN1_TYPE *pkinit_data = NULL; STACK_OF(X509) * cert_stack = NULL; ASN1_OCTET_STRING *digest_attr = NULL; EVP_MD_CTX ctx, ctx2; const EVP_MD *md_tmp = NULL; unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE]; --- 871,880 ----
*** 869,879 **** X509_ALGOR *alg = NULL; ASN1_OCTET_STRING *digest = NULL; unsigned int alg_len = 0, digest_len = 0; unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL; X509 *cert = NULL; ! ASN1_OBJECT *oid = NULL; /* Solaris Kerberos */ if (signed_data == NULL) return EINVAL; --- 886,896 ---- X509_ALGOR *alg = NULL; ASN1_OCTET_STRING *digest = NULL; unsigned int alg_len = 0, digest_len = 0; unsigned char *y = NULL, *alg_buf = NULL, *digest_buf = NULL; X509 *cert = NULL; ! ASN1_OBJECT *oid = NULL, *oid_copy; /* Solaris Kerberos */ if (signed_data == NULL) return EINVAL;
*** 994,1005 **** ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len); PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest, V_ASN1_OCTET_STRING, (char *) digest_attr); /* create a content-type attr */ PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, ! V_ASN1_OBJECT, oid); /* create the signature over signed attributes. get DER encoded value */ /* This is the place where smartcard signature needs to be calculated */ sk = p7si->auth_attr; alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf, --- 1011,1025 ---- ASN1_OCTET_STRING_set(digest_attr, md_data, (int)md_len); PKCS7_add_signed_attribute(p7si, NID_pkcs9_messageDigest, V_ASN1_OCTET_STRING, (char *) digest_attr); /* create a content-type attr */ + oid_copy = OBJ_dup(oid); + if (oid_copy == NULL) + goto cleanup2; PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, ! V_ASN1_OBJECT, oid_copy); /* create the signature over signed attributes. get DER encoded value */ /* This is the place where smartcard signature needs to be calculated */ sk = p7si->auth_attr; alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf,
*** 1092,1121 **** /* adder signer_info to pkcs7 signed */ if (!PKCS7_add_signer(p7, p7si)) goto cleanup2; /* start on adding data to the pkcs7 signed */ ! if ((inner_p7 = PKCS7_new()) == NULL) ! goto cleanup2; ! if ((pkinit_data = ASN1_TYPE_new()) == NULL) ! goto cleanup2; ! pkinit_data->type = V_ASN1_OCTET_STRING; ! if ((pkinit_data->value.octet_string = ASN1_OCTET_STRING_new()) == NULL) ! goto cleanup2; ! if (!ASN1_OCTET_STRING_set(pkinit_data->value.octet_string, data, ! (int)data_len)) { ! unsigned long err = ERR_peek_error(); ! retval = KRB5KDC_ERR_PREAUTH_FAILED; ! krb5_set_error_message(context, retval, "%s\n", ! ERR_error_string(err, NULL)); ! pkiDebug("failed to add pkcs7 data\n"); ! goto cleanup2; ! } ! ! if (!PKCS7_set0_type_other(inner_p7, OBJ_obj2nid(oid), pkinit_data)) ! goto cleanup2; ! if (p7s->contents != NULL) PKCS7_free(p7s->contents); p7s->contents = inner_p7; *signed_data_len = i2d_PKCS7(p7, NULL); --- 1112,1122 ---- /* adder signer_info to pkcs7 signed */ if (!PKCS7_add_signer(p7, p7si)) goto cleanup2; /* start on adding data to the pkcs7 signed */ ! retval = create_contentinfo(context, oid, data, data_len, &inner_p7); if (p7s->contents != NULL) PKCS7_free(p7s->contents); p7s->contents = inner_p7; *signed_data_len = i2d_PKCS7(p7, NULL);
*** 1222,1232 **** #ifdef DEBUG_ASN1 print_buffer_bin(signed_data, signed_data_len, "/tmp/client_received_pkcs7_signeddata"); #endif - /* Do this early enough to create the shadow OID for pkcs7-data if needed */ oid = pkinit_pkcs7type2oid(plgctx, cms_msg_type); if (oid == NULL) goto cleanup; /* decode received PKCS7 message */ --- 1223,1232 ----
*** 3125,3159 **** } static ASN1_OBJECT * pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type) { - int nid; - switch (pkcs7_type) { case CMS_SIGN_CLIENT: return cryptoctx->id_pkinit_authData; case CMS_SIGN_DRAFT9: ! /* ! * Delay creating this OID until we know we need it. ! * It shadows an existing OpenSSL oid. If it ! * is created too early, it breaks things like ! * the use of pkcs12 (which uses pkcs7 structures). ! * We need this shadow version because our code ! * depends on the "other" type to be unknown to the ! * OpenSSL code. ! */ ! if (cryptoctx->id_pkinit_authData9 == NULL) { ! pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n", ! __FUNCTION__); ! nid = OBJ_create("1.2.840.113549.1.7.1", "id-pkcs7-data", ! "PKCS7 data"); ! if (nid == NID_undef) ! return NULL; ! cryptoctx->id_pkinit_authData9 = OBJ_nid2obj(nid); ! } ! return cryptoctx->id_pkinit_authData9; case CMS_SIGN_SERVER: return cryptoctx->id_pkinit_DHKeyData; case CMS_ENVEL_SERVER: return cryptoctx->id_pkinit_rkeyData; default: --- 3125,3139 ---- } static ASN1_OBJECT * pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type) { switch (pkcs7_type) { case CMS_SIGN_CLIENT: return cryptoctx->id_pkinit_authData; case CMS_SIGN_DRAFT9: ! return OBJ_nid2obj(NID_pkcs7_data); case CMS_SIGN_SERVER: return cryptoctx->id_pkinit_DHKeyData; case CMS_ENVEL_SERVER: return cryptoctx->id_pkinit_rkeyData; default: