s4-backupkey: Ensure RSA modulus is 2048 bits
authorArvid Requate <requate@univention.de>
Mon, 7 Jul 2014 15:39:51 +0000 (17:39 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 25 Feb 2015 00:08:10 +0000 (01:08 +0100)
RSA_generate_key_ex doesn't always generate a modulus of requested
bit length. Tests with Windows 7 clients showed that they decline
x509 certificates (MS-BKRP 2.2.1) in cases where the modulus length
is smaller than the specified 2048 bits. For the user this resulted
in DPAPI failing to retrieve stored credentials after the user password
has been changed at least two times. On the server side log.samba showed
that the client also called the as yet unlimplemented ServerWrap sub-
protocol function BACKUPKEY_BACKUP_KEY_GUID after it had called the
ClientWarp function BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID. After
enabling DPAPI auditing on the Windows Clients the Event Viewer showed
Event-ID 4692 failing with a FailureReason value of 0x7a in these cases.

Signed-off-by: Arvid Requate <requate@univention.de>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=10980

source4/rpc_server/backupkey/dcesrv_backupkey.c

index 9020da75cdad8697912d1feb9c1c716f3f0a088a..7daa500ce5a335d525e1cee30339850a6a4b58c6 100644 (file)
@@ -759,6 +759,7 @@ static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,
        uint8_t *p0, *p;
        size_t len;
        int bits = 2048;
+       int RSA_returned_bits;
 
        *_rsa = NULL;
 
@@ -776,11 +777,15 @@ static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,
                return WERR_INTERNAL_ERROR;
        }
 
-       ret = RSA_generate_key_ex(rsa, bits, pub_expo, NULL);
-       if(ret != 1) {
-               RSA_free(rsa);
-               BN_free(pub_expo);
-               return WERR_INTERNAL_ERROR;
+       while (RSA_returned_bits != bits) {
+               ret = RSA_generate_key_ex(rsa, bits, pub_expo, NULL);
+               if(ret != 1) {
+                       RSA_free(rsa);
+                       BN_free(pub_expo);
+                       return WERR_INTERNAL_ERROR;
+               }
+               RSA_returned_bits = BN_num_bits(rsa->n);
+               DEBUG(6, ("RSA_generate_key_ex returned %d Bits\n", RSA_returned_bits));
        }
        BN_free(pub_expo);