s4-backupkey: Set defined cert serialnumber
authorArvid Requate <requate@univention.de>
Mon, 7 Jul 2014 16:18:30 +0000 (18:18 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 25 Feb 2015 00:08:11 +0000 (01:08 +0100)
[MS-BKRP] 2.2.1 specifies that the serialnumber of the certificate
should be set identical to the subjectUniqueID. In fact certificates
generated by native AD have this field encoded in little-endian format.
See also
https://www.mail-archive.com/cifs-protocol@cifs.org/msg01364.html

Signed-off-by: Arvid Requate <requate@univention.de>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
source4/rpc_server/backupkey/dcesrv_backupkey.c

index 5db7685e67ea3217cce3003d2b38a48773af28d7..f748cd1c395c9af40f879e864d08bed40fccd78b 100644 (file)
@@ -833,7 +833,8 @@ static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request
        hx509_name subject = NULL;
        hx509_ca_tbs tbs;
        struct heim_bit_string uniqueid;
-       int ret;
+       struct heim_integer serialnumber;
+       int ret, i;
 
        uniqueid.data = talloc_memdup(ctx, guidblob->data, guidblob->length);
        if (uniqueid.data == NULL) {
@@ -845,6 +846,22 @@ static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request
         */
        uniqueid.length = 8 * guidblob->length;
 
+       serialnumber.data = talloc_array(ctx, uint8_t,
+                                           guidblob->length);
+       if (serialnumber.data == NULL) {
+               talloc_free(uniqueid.data);
+               return WERR_NOMEM;
+       }
+
+       /* Native AD generates certificates with serialnumber in reversed notation */
+       for (i = 0; i < guidblob->length; i++) {
+               uint8_t *reversed = (uint8_t *)serialnumber.data;
+               uint8_t *uncrypt = guidblob->data;
+               reversed[i] = uncrypt[guidblob->length - 1 - i];
+       }
+       serialnumber.length = guidblob->length;
+       serialnumber.negative = 0;
+
        memset(&spki, 0, sizeof(spki));
 
        ret = hx509_request_get_name(*hctx, *req, &subject);
@@ -881,6 +898,10 @@ static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request
        if (ret !=0) {
                goto fail;
        }
+       ret = hx509_ca_tbs_set_serialnumber(*hctx, tbs, &serialnumber);
+       if (ret !=0) {
+               goto fail;
+       }
        ret = hx509_ca_sign_self(*hctx, tbs, *private_key, cert);
        if (ret !=0) {
                goto fail;