The branch, master has been updated via defa49e s4-torture: Remove obsolte code in backupkey_heimdal rpc test via 39bd6f0 s4-torture: Improve backupkey test to validate the self signed cert via eb11fba s4-torture: Add a GnuTLS based backupkey rpc test via 59c11db s4-torture: Rename backupkey test to backupkey_heimdal via 97765d4 s4-rpc_server: Add a GnuTLS based backupkey implementation via 53e8fee waf: Check for GnuTLS 3.4.7 via 8e09669 s4-rpc-bkrp: Do not set the ca status via e8ce1f2 s4-rpc_server: Rename dcesrv_backupkey to dcesrv_backupkey_heimdal via 39ec708 s4-torture: make sure we always verify ndr pull and push of bkrp_exported_RSA_key_pair struct. from 2f16675 ping_pong: add -l option
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit defa49e00c5921ab44fdab53de73918d0732aeda Author: Andreas Schneider <a...@samba.org> Date: Thu Dec 3 18:26:09 2015 +0100 s4-torture: Remove obsolte code in backupkey_heimdal rpc test Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Thu Dec 10 11:54:00 CET 2015 on sn-devel-104 commit 39bd6f06660f1c4daf8020f78a9e66335a5b9425 Author: Andreas Schneider <a...@samba.org> Date: Thu Dec 3 18:25:11 2015 +0100 s4-torture: Improve backupkey test to validate the self signed cert Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit eb11fbaaf71310ec4869f1ca64319012503b11fc Author: Andreas Schneider <a...@samba.org> Date: Thu Dec 3 18:21:03 2015 +0100 s4-torture: Add a GnuTLS based backupkey rpc test Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit 59c11db03d4c3e0c53b27d685e406de16c52e2a3 Author: Andreas Schneider <a...@samba.org> Date: Thu Dec 3 18:10:51 2015 +0100 s4-torture: Rename backupkey test to backupkey_heimdal Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit 97765d48f625738135b6cfe9fb55fa9bc6eba5e0 Author: Andreas Schneider <a...@samba.org> Date: Thu Dec 3 18:04:02 2015 +0100 s4-rpc_server: Add a GnuTLS based backupkey implementation Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit 53e8feeb6ad06c2345936a69b47769d1117e5e59 Author: Andreas Schneider <a...@samba.org> Date: Thu Dec 3 17:47:14 2015 +0100 waf: Check for GnuTLS 3.4.7 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit 8e096698af8f9fb35fbca5da20c552bf486d2b5e Author: Andreas Schneider <a...@samba.org> Date: Wed Dec 9 08:29:45 2015 +0100 s4-rpc-bkrp: Do not set the ca status Windows doesn't have any CA data set on the certificate. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit e8ce1f247762c74cf1a33414afaaeb30cd9293db Author: Andreas Schneider <a...@samba.org> Date: Thu Dec 3 17:12:05 2015 +0100 s4-rpc_server: Rename dcesrv_backupkey to dcesrv_backupkey_heimdal Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit 39ec70862214a9810cbbb63f7e99daecbeed6608 Author: Günther Deschner <g...@samba.org> Date: Fri Nov 13 11:15:41 2015 +0100 s4-torture: make sure we always verify ndr pull and push of bkrp_exported_RSA_key_pair struct. Guenther Signed-off-by: Günther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> ----------------------------------------------------------------------- Summary of changes: source4/lib/tls/wscript | 26 +- source4/rpc_server/backupkey/dcesrv_backupkey.c | 1042 ++++++++++---------- ...esrv_backupkey.c => dcesrv_backupkey_heimdal.c} | 4 - source4/rpc_server/wscript_build | 24 +- source4/torture/ndr/backupkey.c | 6 +- source4/torture/rpc/backupkey.c | 767 +++++++++----- .../rpc/{backupkey.c => backupkey_heimdal.c} | 115 +-- source4/torture/wscript_build | 7 +- 8 files changed, 1111 insertions(+), 880 deletions(-) copy source4/rpc_server/backupkey/{dcesrv_backupkey.c => dcesrv_backupkey_heimdal.c} (99%) copy source4/torture/rpc/{backupkey.c => backupkey_heimdal.c} (98%) Changeset truncated at 500 lines: diff --git a/source4/lib/tls/wscript b/source4/lib/tls/wscript index 83520a7..2083409 100644 --- a/source4/lib/tls/wscript +++ b/source4/lib/tls/wscript @@ -21,14 +21,28 @@ def configure(conf): conf.fatal("--disable-gnutls given: Building the AD DC requires GnuTLS (eg libgnutls-dev, gnutls-devel) for ldaps:// support and for the BackupKey protocol") return - if conf.CHECK_CFG(package='gnutls', - args='"gnutls >= 3.0.0" --cflags --libs', - msg='Checking for gnutls >= 3.0.0s', mandatory=False): + if Options.options.with_system_mitkrb5 and conf.env.AD_DC_BUILD_IS_ENABLED: + conf.CHECK_CFG(package='gnutls', + args='"gnutls >= 3.4.7" --cflags --libs', + msg='Checking for gnutls >= 3.4.7', + mandatory=True) + conf.DEFINE('HAVE_GNUTLS_3_4_7', 1) conf.DEFINE('HAVE_GNUTLS3', 1) else: - conf.CHECK_CFG(package='gnutls', - args='"gnutls >= 1.4.0 gnutls != 2.2.4 gnutls != 2.8.0 gnutls != 2.8.1" --cflags --libs', - msg='Checking for gnutls >= 1.4.0 and broken versions', mandatory=False) + if conf.CHECK_CFG(package='gnutls', + args='"gnutls >= 3.4.7" --cflags --libs', + msg='Checking for gnutls >= 3.4.7', + mandatory=False): + conf.DEFINE('HAVE_GNUTLS_3_4_7', 1) + conf.DEFINE('HAVE_GNUTLS3', 1) + elif conf.CHECK_CFG(package='gnutls', + args='"gnutls >= 3.0.0" --cflags --libs', + msg='Checking for gnutls >= 3.0.0s', mandatory=False): + conf.DEFINE('HAVE_GNUTLS3', 1) + else: + conf.CHECK_CFG(package='gnutls', + args='"gnutls >= 1.4.0 gnutls != 2.2.4 gnutls != 2.8.0 gnutls != 2.8.1" --cflags --libs', + msg='Checking for gnutls >= 1.4.0 and broken versions', mandatory=False) if 'HAVE_GNUTLS' in conf.env: conf.DEFINE('ENABLE_GNUTLS', 1) diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c index 8636e0f..eabaeea 100644 --- a/source4/rpc_server/backupkey/dcesrv_backupkey.c +++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c @@ -4,6 +4,7 @@ endpoint server for the backupkey interface Copyright (C) Matthieu Patou <m...@samba.org> 2010 + Copyright (C) Andreas Schneider <a...@samba.org> 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,30 +30,15 @@ #include "param/param.h" #include "auth/session.h" #include "system/network.h" -#include <com_err.h> -#include <hx509.h> -#include <hcrypto/rsa.h> -#include <hcrypto/bn.h> -#include <hcrypto/sha.h> -#include <hcrypto/evp.h> -#include <hcrypto/hmac.h> -#include <der.h> + #include "../lib/tsocket/tsocket.h" #include "../libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" -#include "lib/crypto/arcfour.h" + #include <gnutls/gnutls.h> #include <gnutls/x509.h> -#if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3) -#include <gcrypt.h> -#endif - - -static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 }; -/* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/ -static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num = { - { 7, discard_const_p(unsigned, rsa_with_var_num) }, NULL -}; +#include <gnutls/crypto.h> +#include <gnutls/abstract.h> static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, @@ -249,147 +235,112 @@ static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx, BIGNUM *bn) +static int reverse_and_get_bignum(TALLOC_CTX *mem_ctx, + DATA_BLOB blob, + gnutls_datum_t *datum) { - DATA_BLOB blob; - DATA_BLOB *rev = talloc(mem_ctx, DATA_BLOB); uint32_t i; - blob.length = BN_num_bytes(bn); - blob.data = talloc_array(mem_ctx, uint8_t, blob.length); - - if (blob.data == NULL) { - return NULL; + datum->data = talloc_array(mem_ctx, uint8_t, blob.length); + if (datum->data == NULL) { + return -1; } - BN_bn2bin(bn, blob.data); - - rev->data = talloc_array(mem_ctx, uint8_t, blob.length); - if (rev->data == NULL) { - return NULL; + for(i = 0; i < blob.length; i++) { + datum->data[i] = blob.data[blob.length - i - 1]; } + datum->size = blob.length; - for(i=0; i < blob.length; i++) { - rev->data[i] = blob.data[blob.length - i -1]; - } - rev->length = blob.length; - talloc_free(blob.data); - return rev; -} - -static BIGNUM *reverse_and_get_bignum(TALLOC_CTX *mem_ctx, DATA_BLOB *blob) -{ - BIGNUM *ret; - DATA_BLOB rev; - uint32_t i; - - rev.data = talloc_array(mem_ctx, uint8_t, blob->length); - if (rev.data == NULL) { - return NULL; - } - - for(i=0; i < blob->length; i++) { - rev.data[i] = blob->data[blob->length - i -1]; - } - rev.length = blob->length; - - ret = BN_bin2bn(rev.data, rev.length, NULL); - talloc_free(rev.data); - - return ret; + return 0; } static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx, struct bkrp_exported_RSA_key_pair *keypair, - hx509_private_key *pk) + gnutls_privkey_t *pk) { - hx509_context hctx; - RSA *rsa; - struct hx509_private_key_ops *ops; - hx509_private_key privkey = NULL; - - hx509_context_init(&hctx); - ops = hx509_find_private_alg(&_hx509_signature_rsa_with_var_num.algorithm); - if (ops == NULL) { - DEBUG(2, ("Not supported algorithm\n")); - hx509_context_free(&hctx); - return NT_STATUS_INTERNAL_ERROR; - } - - if (hx509_private_key_init(&privkey, ops, NULL) != 0) { - hx509_context_free(&hctx); - return NT_STATUS_NO_MEMORY; - } + gnutls_x509_privkey_t x509_privkey = NULL; + gnutls_privkey_t privkey = NULL; + gnutls_datum_t m, e, d, p, q, u, e1, e2; + int rc; - rsa = RSA_new(); - if (rsa ==NULL) { - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + rc = reverse_and_get_bignum(ctx, keypair->modulus, &m); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - - rsa->n = reverse_and_get_bignum(ctx, &(keypair->modulus)); - if (rsa->n == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + rc = reverse_and_get_bignum(ctx, keypair->public_exponent, &e); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - rsa->d = reverse_and_get_bignum(ctx, &(keypair->private_exponent)); - if (rsa->d == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + rc = reverse_and_get_bignum(ctx, keypair->private_exponent, &d); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - rsa->p = reverse_and_get_bignum(ctx, &(keypair->prime1)); - if (rsa->p == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + + rc = reverse_and_get_bignum(ctx, keypair->prime1, &p); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - rsa->q = reverse_and_get_bignum(ctx, &(keypair->prime2)); - if (rsa->q == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + rc = reverse_and_get_bignum(ctx, keypair->prime2, &q); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - rsa->dmp1 = reverse_and_get_bignum(ctx, &(keypair->exponent1)); - if (rsa->dmp1 == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + + rc = reverse_and_get_bignum(ctx, keypair->coefficient, &u); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - rsa->dmq1 = reverse_and_get_bignum(ctx, &(keypair->exponent2)); - if (rsa->dmq1 == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + + rc = reverse_and_get_bignum(ctx, keypair->exponent1, &e1); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - rsa->iqmp = reverse_and_get_bignum(ctx, &(keypair->coefficient)); - if (rsa->iqmp == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); + rc = reverse_and_get_bignum(ctx, keypair->exponent2, &e2); + if (rc != 0) { return NT_STATUS_INVALID_PARAMETER; } - rsa->e = reverse_and_get_bignum(ctx, &(keypair->public_exponent)); - if (rsa->e == NULL) { - RSA_free(rsa); - hx509_private_key_free(&privkey); - hx509_context_free(&hctx); - return NT_STATUS_INVALID_PARAMETER; + + rc = gnutls_x509_privkey_init(&x509_privkey); + if (rc != GNUTLS_E_SUCCESS) { + DBG_ERR("gnutls_x509_privkey_init failed - %s\n", + gnutls_strerror(rc)); + return NT_STATUS_INTERNAL_ERROR; } - *pk = privkey; + rc = gnutls_x509_privkey_import_rsa_raw2(x509_privkey, + &m, + &e, + &d, + &p, + &q, + &u, + &e1, + &e2); + if (rc != GNUTLS_E_SUCCESS) { + DBG_ERR("gnutls_x509_privkey_import_rsa_raw2 failed - %s\n", + gnutls_strerror(rc)); + return NT_STATUS_INTERNAL_ERROR; + } + + rc = gnutls_privkey_init(&privkey); + if (rc != GNUTLS_E_SUCCESS) { + DBG_ERR("gnutls_privkey_init failed - %s\n", + gnutls_strerror(rc)); + gnutls_x509_privkey_deinit(x509_privkey); + return NT_STATUS_INTERNAL_ERROR; + } - hx509_private_key_assign_rsa(*pk, rsa); + rc = gnutls_privkey_import_x509(privkey, + x509_privkey, + GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); + if (rc != GNUTLS_E_SUCCESS) { + DBG_ERR("gnutls_privkey_import_x509 failed - %s\n", + gnutls_strerror(rc)); + gnutls_x509_privkey_deinit(x509_privkey); + return NT_STATUS_INTERNAL_ERROR; + } + + *pk = privkey; - hx509_context_free(&hctx); return NT_STATUS_OK; } @@ -400,102 +351,86 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx, uint32_t access_check_len, struct auth_session_info *session_info) { - heim_octet_string iv; - heim_octet_string access_check_os; - hx509_crypto crypto; - + gnutls_cipher_hd_t cipher_handle = { 0 }; + gnutls_cipher_algorithm_t cipher_algo; DATA_BLOB blob_us; - uint32_t key_len; - uint32_t iv_len; - int res; enum ndr_err_code ndr_err; - hx509_context hctx; + gnutls_datum_t key; + gnutls_datum_t iv; struct dom_sid *access_sid = NULL; struct dom_sid *caller_sid = NULL; - - /* This one should not be freed */ - const AlgorithmIdentifier *alg; + int rc; switch (version) { case 2: - key_len = 24; - iv_len = 8; - alg = hx509_crypto_des_rsdi_ede3_cbc(); + cipher_algo = GNUTLS_CIPHER_3DES_CBC; break; - case 3: - key_len = 32; - iv_len = 16; - alg =hx509_crypto_aes256_cbc(); + cipher_algo = GNUTLS_CIPHER_AES_256_CBC; break; - default: return WERR_INVALID_DATA; } - hx509_context_init(&hctx); - res = hx509_crypto_init(hctx, NULL, - &(alg->algorithm), - &crypto); - hx509_context_free(&hctx); + key.data = key_and_iv; + key.size = gnutls_cipher_get_key_size(cipher_algo); - if (res != 0) { + iv.data = key_and_iv + key.size; + iv.size = gnutls_cipher_get_iv_size(cipher_algo); + + /* Allocate data structure for the plaintext */ + blob_us = data_blob_talloc_zero(sub_ctx, access_check_len); + if (blob_us.data == NULL) { return WERR_INVALID_DATA; } - res = hx509_crypto_set_key_data(crypto, key_and_iv, key_len); - - iv.data = talloc_memdup(sub_ctx, key_len + key_and_iv, iv_len); - iv.length = iv_len; - - if (res != 0) { - hx509_crypto_destroy(crypto); + rc = gnutls_cipher_init(&cipher_handle, + cipher_algo, + &key, + &iv); + if (rc < 0) { + DBG_ERR("gnutls_cipher_init failed: %s\n", + gnutls_strerror(rc)); return WERR_INVALID_DATA; } - hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE); - res = hx509_crypto_decrypt(crypto, - access_check, - access_check_len, - &iv, - &access_check_os); - - if (res != 0) { - hx509_crypto_destroy(crypto); + rc = gnutls_cipher_decrypt2(cipher_handle, + access_check, + access_check_len, + blob_us.data, + blob_us.length); + gnutls_cipher_deinit(cipher_handle); + if (rc < 0) { + DBG_ERR("gnutls_cipher_decrypt2 failed: %s\n", + gnutls_strerror(rc)); return WERR_INVALID_DATA; } - blob_us.data = access_check_os.data; - blob_us.length = access_check_os.length; - - hx509_crypto_destroy(crypto); - switch (version) { case 2: { uint32_t hash_size = 20; uint8_t hash[hash_size]; - struct sha sctx; + gnutls_hash_hd_t dig_ctx; struct bkrp_access_check_v2 uncrypted_accesscheckv2; ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv2, (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v2); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { /* Unable to unmarshall */ - der_free_octet_string(&access_check_os); return WERR_INVALID_DATA; } if (uncrypted_accesscheckv2.magic != 0x1) { /* wrong magic */ - der_free_octet_string(&access_check_os); return WERR_INVALID_DATA; } - SHA1_Init(&sctx); - SHA1_Update(&sctx, blob_us.data, blob_us.length - hash_size); - SHA1_Final(hash, &sctx); - der_free_octet_string(&access_check_os); + gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA1); + gnutls_hash(dig_ctx, + blob_us.data, + blob_us.length - hash_size); + gnutls_hash_deinit(dig_ctx, hash); /* * We free it after the sha1 calculation because blob.data * point to the same area @@ -512,26 +447,26 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx, { uint32_t hash_size = 64; uint8_t hash[hash_size]; - struct hc_sha512state sctx; + gnutls_hash_hd_t dig_ctx; struct bkrp_access_check_v3 uncrypted_accesscheckv3; ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv3, (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v3); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { /* Unable to unmarshall */ - der_free_octet_string(&access_check_os); return WERR_INVALID_DATA; } if (uncrypted_accesscheckv3.magic != 0x1) { /* wrong magic */ - der_free_octet_string(&access_check_os); return WERR_INVALID_DATA; } - SHA512_Init(&sctx); - SHA512_Update(&sctx, blob_us.data, blob_us.length - hash_size); - SHA512_Final(hash, &sctx); - der_free_octet_string(&access_check_os); + gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA512); + gnutls_hash(dig_ctx, + blob_us.data, + blob_us.length - hash_size); + gnutls_hash_deinit(dig_ctx, hash); + /* * We free it after the sha1 calculation because blob.data * point to the same area @@ -642,15 +577,14 @@ static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, /* we do not have the real secret attribute, like if we are an RODC */ return WERR_INVALID_PARAMETER; } else { - hx509_context hctx; struct bkrp_exported_RSA_key_pair keypair; - hx509_private_key pk; - uint32_t i, res; - heim_octet_string reversed_secret; - heim_octet_string uncrypted_secret; - AlgorithmIdentifier alg; + gnutls_privkey_t privkey = NULL; + gnutls_datum_t reversed_secret; + gnutls_datum_t uncrypted_secret; + uint32_t i; DATA_BLOB blob_us; WERROR werr; + int rc; -- Samba Shared Repository