9cd912594c5cfd1224ee4ba01ab2c0ea63949d6b
[samba.git] / source4 / rpc_server / backupkey / dcesrv_backupkey_heimdal.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the backupkey interface
5
6    Copyright (C) Matthieu Patou <mat@samba.org> 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "rpc_server/dcerpc_server.h"
24 #include "rpc_server/common/common.h"
25 #include "librpc/gen_ndr/ndr_backupkey.h"
26 #include "dsdb/common/util.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "lib/ldb/include/ldb_errors.h"
29 #include "../lib/util/util_ldb.h"
30 #include "param/param.h"
31 #include "auth/session.h"
32 #include "system/network.h"
33 #include <com_err.h>
34 #include <hx509.h>
35 #include <hcrypto/rsa.h>
36 #include <hcrypto/bn.h>
37 #include <hcrypto/sha.h>
38 #include <hcrypto/evp.h>
39 #include <hcrypto/hmac.h>
40 #include <der.h>
41 #include "../lib/tsocket/tsocket.h"
42 #include "../libcli/security/security.h"
43 #include "librpc/gen_ndr/ndr_security.h"
44 #include "lib/crypto/arcfour.h"
45 #include "libds/common/roles.h"
46 #include <gnutls/gnutls.h>
47 #include <gnutls/x509.h>
48 #if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3)
49 #include <gcrypt.h>
50 #endif
51
52 #define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \
53         dcesrv_interface_backupkey_bind(call, iface)
54 static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call,
55                                                 const struct dcesrv_interface *iface)
56 {
57         return dcesrv_interface_bind_require_privacy(dce_call, iface);
58 }
59
60 static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 };
61 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/
62 static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num = {
63         { 7, discard_const_p(unsigned, rsa_with_var_num) }, NULL
64 };
65
66 static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
67                                struct ldb_context *ldb,
68                                const char *name,
69                                const DATA_BLOB *lsa_secret)
70 {
71         struct ldb_message *msg;
72         struct ldb_result *res;
73         struct ldb_dn *domain_dn;
74         struct ldb_dn *system_dn;
75         struct ldb_val val;
76         int ret;
77         char *name2;
78         struct timeval now = timeval_current();
79         NTTIME nt_now = timeval_to_nttime(&now);
80         const char *attrs[] = {
81                 NULL
82         };
83
84         domain_dn = ldb_get_default_basedn(ldb);
85         if (!domain_dn) {
86                 return NT_STATUS_INTERNAL_ERROR;
87         }
88
89         msg = ldb_msg_new(mem_ctx);
90         if (msg == NULL) {
91                 return NT_STATUS_NO_MEMORY;
92         }
93
94         /*
95          * This function is a lot like dcesrv_lsa_CreateSecret
96          * in the rpc_server/lsa directory
97          * The reason why we duplicate the effort here is that:
98          * * we want to keep the former function static
99          * * we want to avoid the burden of doing LSA calls
100          *   when we can just manipulate the secrets directly
101          * * taillor the function to the particular needs of backup protocol
102          */
103
104         system_dn = samdb_search_dn(ldb, msg, domain_dn, "(&(objectClass=container)(cn=System))");
105         if (system_dn == NULL) {
106                 talloc_free(msg);
107                 return NT_STATUS_NO_MEMORY;
108         }
109
110         name2 = talloc_asprintf(msg, "%s Secret", name);
111         if (name2 == NULL) {
112                 talloc_free(msg);
113                 return NT_STATUS_NO_MEMORY;
114         }
115
116         ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
117                            "(&(cn=%s)(objectclass=secret))",
118                            ldb_binary_encode_string(mem_ctx, name2));
119
120         if (ret != LDB_SUCCESS ||  res->count != 0 ) {
121                 DEBUG(2, ("Secret %s already exists !\n", name2));
122                 talloc_free(msg);
123                 return NT_STATUS_OBJECT_NAME_COLLISION;
124         }
125
126         /*
127          * We don't care about previous value as we are
128          * here only if the key didn't exists before
129          */
130
131         msg->dn = ldb_dn_copy(mem_ctx, system_dn);
132         if (msg->dn == NULL) {
133                 talloc_free(msg);
134                 return NT_STATUS_NO_MEMORY;
135         }
136         if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
137                 talloc_free(msg);
138                 return NT_STATUS_NO_MEMORY;
139         }
140
141         ret = ldb_msg_add_string(msg, "cn", name2);
142         if (ret != LDB_SUCCESS) {
143                 talloc_free(msg);
144                 return NT_STATUS_NO_MEMORY;
145         }
146         ret = ldb_msg_add_string(msg, "objectClass", "secret");
147         if (ret != LDB_SUCCESS) {
148                 talloc_free(msg);
149                 return NT_STATUS_NO_MEMORY;
150         }
151         ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "priorSetTime", nt_now);
152         if (ret != LDB_SUCCESS) {
153                 talloc_free(msg);
154                 return NT_STATUS_NO_MEMORY;
155         }
156         val.data = lsa_secret->data;
157         val.length = lsa_secret->length;
158         ret = ldb_msg_add_value(msg, "currentValue", &val, NULL);
159         if (ret != LDB_SUCCESS) {
160                 talloc_free(msg);
161                 return NT_STATUS_NO_MEMORY;
162         }
163         ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "lastSetTime", nt_now);
164         if (ret != LDB_SUCCESS) {
165                 talloc_free(msg);
166                 return NT_STATUS_NO_MEMORY;
167         }
168
169         /*
170          * create the secret with DSDB_MODIFY_RELAX
171          * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
172          * the create of LSA secret object
173          */
174         ret = dsdb_add(ldb, msg, DSDB_MODIFY_RELAX);
175         if (ret != LDB_SUCCESS) {
176                 DEBUG(2,("Failed to create secret record %s: %s\n",
177                         ldb_dn_get_linearized(msg->dn),
178                         ldb_errstring(ldb)));
179                 talloc_free(msg);
180                 return NT_STATUS_ACCESS_DENIED;
181         }
182
183         talloc_free(msg);
184         return NT_STATUS_OK;
185 }
186
187 /* This function is pretty much like dcesrv_lsa_QuerySecret */
188 static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
189                                struct ldb_context *ldb,
190                                const char *name,
191                                DATA_BLOB *lsa_secret)
192 {
193         TALLOC_CTX *tmp_mem;
194         struct ldb_result *res;
195         struct ldb_dn *domain_dn;
196         struct ldb_dn *system_dn;
197         const struct ldb_val *val;
198         uint8_t *data;
199         const char *attrs[] = {
200                 "currentValue",
201                 NULL
202         };
203         int ret;
204
205         lsa_secret->data = NULL;
206         lsa_secret->length = 0;
207
208         domain_dn = ldb_get_default_basedn(ldb);
209         if (!domain_dn) {
210                 return NT_STATUS_INTERNAL_ERROR;
211         }
212
213         tmp_mem = talloc_new(mem_ctx);
214         if (tmp_mem == NULL) {
215                 return NT_STATUS_NO_MEMORY;
216         }
217
218         system_dn = samdb_search_dn(ldb, tmp_mem, domain_dn, "(&(objectClass=container)(cn=System))");
219         if (system_dn == NULL) {
220                 talloc_free(tmp_mem);
221                 return NT_STATUS_NO_MEMORY;
222         }
223
224         ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
225                            "(&(cn=%s Secret)(objectclass=secret))",
226                            ldb_binary_encode_string(tmp_mem, name));
227
228         if (ret != LDB_SUCCESS) {
229                 talloc_free(tmp_mem);
230                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
231         }
232         if (res->count == 0) {
233                 talloc_free(tmp_mem);
234                 return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
235         }
236         if (res->count > 1) {
237                 DEBUG(2, ("Secret %s collision\n", name));
238                 talloc_free(tmp_mem);
239                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
240         }
241
242         val = ldb_msg_find_ldb_val(res->msgs[0], "currentValue");
243         if (val == NULL) {
244                 /*
245                  * The secret object is here but we don't have the secret value
246                  * The most common case is a RODC
247                  */
248                 *lsa_secret = data_blob_null;
249                 talloc_free(tmp_mem);
250                 return NT_STATUS_OK;
251         }
252
253         data = val->data;
254         lsa_secret->data = talloc_move(mem_ctx, &data);
255         lsa_secret->length = val->length;
256
257         talloc_free(tmp_mem);
258         return NT_STATUS_OK;
259 }
260
261 static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx, BIGNUM *bn)
262 {
263         DATA_BLOB blob;
264         DATA_BLOB *rev = talloc(mem_ctx, DATA_BLOB);
265         uint32_t i;
266
267         blob.length = BN_num_bytes(bn);
268         blob.data = talloc_array(mem_ctx, uint8_t, blob.length);
269
270         if (blob.data == NULL) {
271                 return NULL;
272         }
273
274         BN_bn2bin(bn, blob.data);
275
276         rev->data = talloc_array(mem_ctx, uint8_t, blob.length);
277         if (rev->data == NULL) {
278                 return NULL;
279         }
280
281         for(i=0; i < blob.length; i++) {
282                 rev->data[i] = blob.data[blob.length - i -1];
283         }
284         rev->length = blob.length;
285         talloc_free(blob.data);
286         return rev;
287 }
288
289 static BIGNUM *reverse_and_get_bignum(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
290 {
291         BIGNUM *ret;
292         DATA_BLOB rev;
293         uint32_t i;
294
295         rev.data = talloc_array(mem_ctx, uint8_t, blob->length);
296         if (rev.data == NULL) {
297                 return NULL;
298         }
299
300         for(i=0; i < blob->length; i++) {
301                 rev.data[i] = blob->data[blob->length - i -1];
302         }
303         rev.length = blob->length;
304
305         ret = BN_bin2bn(rev.data, rev.length, NULL);
306         talloc_free(rev.data);
307
308         return ret;
309 }
310
311 static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx,
312                                 struct bkrp_exported_RSA_key_pair *keypair,
313                                 hx509_private_key *pk)
314 {
315         hx509_context hctx;
316         RSA *rsa;
317         struct hx509_private_key_ops *ops;
318         hx509_private_key privkey = NULL;
319
320         hx509_context_init(&hctx);
321         ops = hx509_find_private_alg(&_hx509_signature_rsa_with_var_num.algorithm);
322         if (ops == NULL) {
323                 DEBUG(2, ("Not supported algorithm\n"));
324                 hx509_context_free(&hctx);
325                 return NT_STATUS_INTERNAL_ERROR;
326         }
327
328         if (hx509_private_key_init(&privkey, ops, NULL) != 0) {
329                 hx509_context_free(&hctx);
330                 return NT_STATUS_NO_MEMORY;
331         }
332
333         rsa = RSA_new();
334         if (rsa ==NULL) {
335                 hx509_private_key_free(&privkey);
336                 hx509_context_free(&hctx);
337                 return NT_STATUS_INVALID_PARAMETER;
338         }
339
340         rsa->n = reverse_and_get_bignum(ctx, &(keypair->modulus));
341         if (rsa->n == NULL) {
342                 RSA_free(rsa);
343                 hx509_private_key_free(&privkey);
344                 hx509_context_free(&hctx);
345                 return NT_STATUS_INVALID_PARAMETER;
346         }
347         rsa->d = reverse_and_get_bignum(ctx, &(keypair->private_exponent));
348         if (rsa->d == NULL) {
349                 RSA_free(rsa);
350                 hx509_private_key_free(&privkey);
351                 hx509_context_free(&hctx);
352                 return NT_STATUS_INVALID_PARAMETER;
353         }
354         rsa->p = reverse_and_get_bignum(ctx, &(keypair->prime1));
355         if (rsa->p == NULL) {
356                 RSA_free(rsa);
357                 hx509_private_key_free(&privkey);
358                 hx509_context_free(&hctx);
359                 return NT_STATUS_INVALID_PARAMETER;
360         }
361         rsa->q = reverse_and_get_bignum(ctx, &(keypair->prime2));
362         if (rsa->q == NULL) {
363                 RSA_free(rsa);
364                 hx509_private_key_free(&privkey);
365                 hx509_context_free(&hctx);
366                 return NT_STATUS_INVALID_PARAMETER;
367         }
368         rsa->dmp1 = reverse_and_get_bignum(ctx, &(keypair->exponent1));
369         if (rsa->dmp1 == NULL) {
370                 RSA_free(rsa);
371                 hx509_private_key_free(&privkey);
372                 hx509_context_free(&hctx);
373                 return NT_STATUS_INVALID_PARAMETER;
374         }
375         rsa->dmq1 = reverse_and_get_bignum(ctx, &(keypair->exponent2));
376         if (rsa->dmq1 == NULL) {
377                 RSA_free(rsa);
378                 hx509_private_key_free(&privkey);
379                 hx509_context_free(&hctx);
380                 return NT_STATUS_INVALID_PARAMETER;
381         }
382         rsa->iqmp = reverse_and_get_bignum(ctx, &(keypair->coefficient));
383         if (rsa->iqmp == NULL) {
384                 RSA_free(rsa);
385                 hx509_private_key_free(&privkey);
386                 hx509_context_free(&hctx);
387                 return NT_STATUS_INVALID_PARAMETER;
388         }
389         rsa->e = reverse_and_get_bignum(ctx, &(keypair->public_exponent));
390         if (rsa->e == NULL) {
391                 RSA_free(rsa);
392                 hx509_private_key_free(&privkey);
393                 hx509_context_free(&hctx);
394                 return NT_STATUS_INVALID_PARAMETER;
395         }
396
397         *pk = privkey;
398
399         hx509_private_key_assign_rsa(*pk, rsa);
400
401         hx509_context_free(&hctx);
402         return NT_STATUS_OK;
403 }
404
405 static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
406                                           uint32_t version,
407                                           uint8_t *key_and_iv,
408                                           uint8_t *access_check,
409                                           uint32_t access_check_len,
410                                           struct auth_session_info *session_info)
411 {
412         heim_octet_string iv;
413         heim_octet_string access_check_os;
414         hx509_crypto crypto;
415
416         DATA_BLOB blob_us;
417         uint32_t key_len;
418         uint32_t iv_len;
419         int res;
420         enum ndr_err_code ndr_err;
421         hx509_context hctx;
422
423         struct dom_sid *access_sid = NULL;
424         struct dom_sid *caller_sid = NULL;
425
426         /* This one should not be freed */
427         const AlgorithmIdentifier *alg;
428
429         switch (version) {
430         case 2:
431                 key_len = 24;
432                 iv_len = 8;
433                 alg = hx509_crypto_des_rsdi_ede3_cbc();
434                 break;
435
436         case 3:
437                 key_len = 32;
438                 iv_len = 16;
439                 alg =hx509_crypto_aes256_cbc();
440                 break;
441
442         default:
443                 return WERR_INVALID_DATA;
444         }
445
446         hx509_context_init(&hctx);
447         res = hx509_crypto_init(hctx, NULL,
448                                 &(alg->algorithm),
449                                 &crypto);
450         hx509_context_free(&hctx);
451
452         if (res != 0) {
453                 return WERR_INVALID_DATA;
454         }
455
456         res = hx509_crypto_set_key_data(crypto, key_and_iv, key_len);
457
458         iv.data = talloc_memdup(sub_ctx, key_len + key_and_iv, iv_len);
459         iv.length = iv_len;
460
461         if (res != 0) {
462                 hx509_crypto_destroy(crypto);
463                 return WERR_INVALID_DATA;
464         }
465
466         hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE);
467         res = hx509_crypto_decrypt(crypto,
468                 access_check,
469                 access_check_len,
470                 &iv,
471                 &access_check_os);
472
473         if (res != 0) {
474                 hx509_crypto_destroy(crypto);
475                 return WERR_INVALID_DATA;
476         }
477
478         blob_us.data = access_check_os.data;
479         blob_us.length = access_check_os.length;
480
481         hx509_crypto_destroy(crypto);
482
483         switch (version) {
484         case 2:
485         {
486                 uint32_t hash_size = 20;
487                 uint8_t hash[hash_size];
488                 struct sha sctx;
489                 struct bkrp_access_check_v2 uncrypted_accesscheckv2;
490
491                 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv2,
492                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v2);
493                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
494                         /* Unable to unmarshall */
495                         der_free_octet_string(&access_check_os);
496                         return WERR_INVALID_DATA;
497                 }
498                 if (uncrypted_accesscheckv2.magic != 0x1) {
499                         /* wrong magic */
500                         der_free_octet_string(&access_check_os);
501                         return WERR_INVALID_DATA;
502                 }
503
504                 SHA1_Init(&sctx);
505                 SHA1_Update(&sctx, blob_us.data, blob_us.length - hash_size);
506                 SHA1_Final(hash, &sctx);
507                 der_free_octet_string(&access_check_os);
508                 /*
509                  * We free it after the sha1 calculation because blob.data
510                  * point to the same area
511                  */
512
513                 if (memcmp(hash, uncrypted_accesscheckv2.hash, hash_size) != 0) {
514                         DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
515                         return WERR_INVALID_DATA;
516                 }
517                 access_sid = &(uncrypted_accesscheckv2.sid);
518                 break;
519         }
520         case 3:
521         {
522                 uint32_t hash_size = 64;
523                 uint8_t hash[hash_size];
524                 struct hc_sha512state sctx;
525                 struct bkrp_access_check_v3 uncrypted_accesscheckv3;
526
527                 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv3,
528                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v3);
529                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
530                         /* Unable to unmarshall */
531                         der_free_octet_string(&access_check_os);
532                         return WERR_INVALID_DATA;
533                 }
534                 if (uncrypted_accesscheckv3.magic != 0x1) {
535                         /* wrong magic */
536                         der_free_octet_string(&access_check_os);
537                         return WERR_INVALID_DATA;
538                 }
539
540                 SHA512_Init(&sctx);
541                 SHA512_Update(&sctx, blob_us.data, blob_us.length - hash_size);
542                 SHA512_Final(hash, &sctx);
543                 der_free_octet_string(&access_check_os);
544                 /*
545                  * We free it after the sha1 calculation because blob.data
546                  * point to the same area
547                  */
548
549                 if (memcmp(hash, uncrypted_accesscheckv3.hash, hash_size) != 0) {
550                         DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
551                         return WERR_INVALID_DATA;
552                 }
553                 access_sid = &(uncrypted_accesscheckv3.sid);
554                 break;
555         }
556         default:
557                 /* Never reached normally as we filtered at the switch / case level */
558                 return WERR_INVALID_DATA;
559         }
560
561         caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
562
563         if (!dom_sid_equal(caller_sid, access_sid)) {
564                 return WERR_INVALID_ACCESS;
565         }
566         return WERR_OK;
567 }
568
569 /*
570  * We have some data, such as saved website or IMAP passwords that the
571  * client has in profile on-disk.  This needs to be decrypted.  This
572  * version gives the server the data over the network (protected by
573  * the X.509 certificate and public key encryption, and asks that it
574  * be decrypted returned for short-term use, protected only by the
575  * negotiated transport encryption.
576  *
577  * The data is NOT stored in the LSA, but a X.509 certificate, public
578  * and private keys used to encrypt the data will be stored.  There is
579  * only one active encryption key pair and certificate per domain, it
580  * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
581  *
582  * The potentially multiple valid decrypting key pairs are in turn
583  * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
584  *
585  */
586 static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
587                                             TALLOC_CTX *mem_ctx,
588                                             struct bkrp_BackupKey *r,
589                                             struct ldb_context *ldb_ctx)
590 {
591         struct auth_session_info *session_info =
592                 dcesrv_call_session_info(dce_call);
593         struct bkrp_client_side_wrapped uncrypt_request;
594         DATA_BLOB blob;
595         enum ndr_err_code ndr_err;
596         char *guid_string;
597         char *cert_secret_name;
598         DATA_BLOB lsa_secret;
599         DATA_BLOB *uncrypted_data = NULL;
600         NTSTATUS status;
601         uint32_t requested_version;
602
603         blob.data = r->in.data_in;
604         blob.length = r->in.data_in_len;
605
606         if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
607                 return WERR_INVALID_PARAMETER;
608         }
609
610         /*
611          * We check for the version here, so we can actually print the
612          * message as we are unlikely to parse it with NDR.
613          */
614         requested_version = IVAL(r->in.data_in, 0);
615         if ((requested_version != BACKUPKEY_CLIENT_WRAP_VERSION2)
616             && (requested_version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
617                 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", requested_version));
618                 return WERR_INVALID_PARAMETER;
619         }
620
621         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request,
622                                        (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped);
623         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
624                 return WERR_INVALID_PARAMETER;
625         }
626
627         if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2)
628             && (uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
629                 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", uncrypt_request.version));
630                 return WERR_INVALID_PARAMETER;
631         }
632
633         guid_string = GUID_string(mem_ctx, &uncrypt_request.guid);
634         if (guid_string == NULL) {
635                 return WERR_NOT_ENOUGH_MEMORY;
636         }
637
638         cert_secret_name = talloc_asprintf(mem_ctx,
639                                            "BCKUPKEY_%s",
640                                            guid_string);
641         if (cert_secret_name == NULL) {
642                 return WERR_NOT_ENOUGH_MEMORY;
643         }
644
645         status = get_lsa_secret(mem_ctx,
646                                 ldb_ctx,
647                                 cert_secret_name,
648                                 &lsa_secret);
649         if (!NT_STATUS_IS_OK(status)) {
650                 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name));
651                 return WERR_INVALID_DATA;
652         } else if (lsa_secret.length == 0) {
653                 /* we do not have the real secret attribute, like if we are an RODC */
654                 return WERR_INVALID_PARAMETER;
655         } else {
656                 hx509_context hctx;
657                 struct bkrp_exported_RSA_key_pair keypair;
658                 hx509_private_key pk;
659                 uint32_t i, res;
660                 heim_octet_string reversed_secret;
661                 heim_octet_string uncrypted_secret;
662                 AlgorithmIdentifier alg;
663                 DATA_BLOB blob_us;
664                 WERROR werr;
665
666                 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
667                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
668                         DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name));
669                         return WERR_FILE_NOT_FOUND;
670                 }
671
672                 status = get_pk_from_raw_keypair_params(mem_ctx, &keypair, &pk);
673                 if (!NT_STATUS_IS_OK(status)) {
674                         return WERR_INTERNAL_ERROR;
675                 }
676
677                 reversed_secret.data = talloc_array(mem_ctx, uint8_t,
678                                                     uncrypt_request.encrypted_secret_len);
679                 if (reversed_secret.data == NULL) {
680                         hx509_private_key_free(&pk);
681                         return WERR_NOT_ENOUGH_MEMORY;
682                 }
683
684                 /* The secret has to be reversed ... */
685                 for(i=0; i< uncrypt_request.encrypted_secret_len; i++) {
686                         uint8_t *reversed = (uint8_t *)reversed_secret.data;
687                         uint8_t *uncrypt = uncrypt_request.encrypted_secret;
688                         reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i];
689                 }
690                 reversed_secret.length = uncrypt_request.encrypted_secret_len;
691
692                 /*
693                  * Let's try to decrypt the secret now that
694                  * we have the private key ...
695                  */
696                 hx509_context_init(&hctx);
697                 res = hx509_private_key_private_decrypt(hctx, &reversed_secret,
698                                                          &alg.algorithm, pk,
699                                                          &uncrypted_secret);
700                 hx509_context_free(&hctx);
701                 hx509_private_key_free(&pk);
702                 if (res != 0) {
703                         /* We are not able to decrypt the secret, looks like something is wrong */
704                         return WERR_INVALID_PARAMETER;
705                 }
706                 blob_us.data = uncrypted_secret.data;
707                 blob_us.length = uncrypted_secret.length;
708
709                 if (uncrypt_request.version == 2) {
710                         struct bkrp_encrypted_secret_v2 uncrypted_secretv2;
711
712                         ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2,
713                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2);
714                         der_free_octet_string(&uncrypted_secret);
715                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
716                                 /* Unable to unmarshall */
717                                 return WERR_INVALID_DATA;
718                         }
719                         if (uncrypted_secretv2.magic != 0x20) {
720                                 /* wrong magic */
721                                 return WERR_INVALID_DATA;
722                         }
723
724                         werr = get_and_verify_access_check(mem_ctx, 2,
725                                                            uncrypted_secretv2.payload_key,
726                                                            uncrypt_request.access_check,
727                                                            uncrypt_request.access_check_len,
728                                                            session_info);
729                         if (!W_ERROR_IS_OK(werr)) {
730                                 return werr;
731                         }
732                         uncrypted_data = talloc(mem_ctx, DATA_BLOB);
733                         if (uncrypted_data == NULL) {
734                                 return WERR_INVALID_DATA;
735                         }
736
737                         uncrypted_data->data = uncrypted_secretv2.secret;
738                         uncrypted_data->length = uncrypted_secretv2.secret_len;
739                 }
740                 if (uncrypt_request.version == 3) {
741                         struct bkrp_encrypted_secret_v3 uncrypted_secretv3;
742
743                         ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3,
744                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v3);
745
746                         der_free_octet_string(&uncrypted_secret);
747                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
748                                 /* Unable to unmarshall */
749                                 return WERR_INVALID_DATA;
750                         }
751
752                         if (uncrypted_secretv3.magic1 != 0x30  ||
753                             uncrypted_secretv3.magic2 != 0x6610 ||
754                             uncrypted_secretv3.magic3 != 0x800e) {
755                                 /* wrong magic */
756                                 return WERR_INVALID_DATA;
757                         }
758
759                         /*
760                          * Confirm that the caller is permitted to
761                          * read this particular data.  Because one key
762                          * pair is used per domain, the caller could
763                          * have stolen the profile data on-disk and
764                          * would otherwise be able to read the
765                          * passwords.
766                          */
767
768                         werr = get_and_verify_access_check(mem_ctx, 3,
769                                                            uncrypted_secretv3.payload_key,
770                                                            uncrypt_request.access_check,
771                                                            uncrypt_request.access_check_len,
772                                                            session_info);
773                         if (!W_ERROR_IS_OK(werr)) {
774                                 return werr;
775                         }
776
777                         uncrypted_data = talloc(mem_ctx, DATA_BLOB);
778                         if (uncrypted_data == NULL) {
779                                 return WERR_INVALID_DATA;
780                         }
781
782                         uncrypted_data->data = uncrypted_secretv3.secret;
783                         uncrypted_data->length = uncrypted_secretv3.secret_len;
784                 }
785
786                 /*
787                  * Yeah if we are here all looks pretty good:
788                  * - hash is ok
789                  * - user sid is the same as the one in access check
790                  * - we were able to decrypt the whole stuff
791                  */
792         }
793
794         if (uncrypted_data->data == NULL) {
795                 return WERR_INVALID_DATA;
796         }
797
798         /* There is a magic value a the beginning of the data
799          * we can use an adhoc structure but as the
800          * parent structure is just an array of bytes it a lot of work
801          * work just prepending 4 bytes
802          */
803         *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted_data->length + 4);
804         W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
805         memcpy(4+*(r->out.data_out), uncrypted_data->data, uncrypted_data->length);
806         *(r->out.data_out_len) = uncrypted_data->length + 4;
807
808         return WERR_OK;
809 }
810
811 /*
812  * Strictly, this function no longer uses Heimdal in order to generate an RSA
813  * key, but GnuTLS.
814  *
815  * The resulting key is then imported into Heimdal's RSA structure.
816  *
817  * We use GnuTLS because it can reliably generate 2048 bit keys every time.
818  * Windows clients strictly require 2048, no more since it won't fit and no
819  * less either. Heimdal would almost always generate a smaller key.
820  */
821 static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,
822                                      hx509_private_key *pk, RSA **rsa)
823 {
824         int ret;
825         uint8_t *p0 = NULL;
826         const uint8_t *p;
827         size_t len;
828         int bits = 2048;
829         int RSA_returned_bits;
830         gnutls_x509_privkey_t gtls_key;
831         WERROR werr;
832
833         *rsa = NULL;
834
835         ret = gnutls_global_init();
836         if (ret != GNUTLS_E_SUCCESS) {
837                 DBG_ERR("TLS error: %s\n", gnutls_strerror(ret));
838                 return WERR_INTERNAL_ERROR;
839         }
840 #if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3)
841         DEBUG(3,("Enabling QUICK mode in gcrypt\n"));
842         gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
843 #endif
844         ret = gnutls_x509_privkey_init(&gtls_key);
845         if (ret != 0) {
846                 gnutls_global_deinit();
847                 return WERR_INTERNAL_ERROR;
848         }
849
850         /*
851          * Unlike Heimdal's RSA_generate_key_ex(), this generates a
852          * 2048 bit key 100% of the time.  The heimdal code had a ~1/8
853          * chance of doing so, chewing vast quantities of computation
854          * and entropy in the process.
855          */
856
857         ret = gnutls_x509_privkey_generate(gtls_key, GNUTLS_PK_RSA, bits, 0);
858         if (ret != 0) {
859                 werr = WERR_INTERNAL_ERROR;
860                 goto done;
861         }
862
863         /* No need to check error code, this SHOULD fail */
864         gnutls_x509_privkey_export(gtls_key, GNUTLS_X509_FMT_DER, NULL, &len);
865
866         if (len < 1) {
867                 werr = WERR_INTERNAL_ERROR;
868                 goto done;
869         }
870
871         p0 = talloc_size(ctx, len);
872         if (p0 == NULL) {
873                 werr = WERR_NOT_ENOUGH_MEMORY;
874                 goto done;
875         }
876         p = p0;
877
878         /*
879          * Only this GnuTLS export function correctly exports the key,
880          * we can't use gnutls_rsa_params_export_raw() because while
881          * it appears to be fixed in more recent versions, in the
882          * Ubuntu 14.04 version 2.12.23 (at least) it incorrectly
883          * exports one of the key parameters (qInv).  Additionally, we
884          * would have to work around subtle differences in big number
885          * representations.
886          *
887          * We need access to the RSA parameters directly (in the
888          * parameter RSA **rsa) as the caller has to manually encode
889          * them in a non-standard data structure.
890          */
891         ret = gnutls_x509_privkey_export(gtls_key, GNUTLS_X509_FMT_DER, p0, &len);
892
893         if (ret != 0) {
894                 werr = WERR_INTERNAL_ERROR;
895                 goto done;
896         }
897
898         /*
899          * To dump the key we can use :
900          * rk_dumpdata("h5lkey", p0, len);
901          */
902         ret = hx509_parse_private_key(*hctx, &_hx509_signature_rsa_with_var_num ,
903                                        p0, len, HX509_KEY_FORMAT_DER, pk);
904
905         if (ret != 0) {
906                 werr = WERR_INTERNAL_ERROR;
907                 goto done;
908         }
909
910         *rsa = d2i_RSAPrivateKey(NULL, &p, len);
911         TALLOC_FREE(p0);
912
913         if (*rsa == NULL) {
914                 hx509_private_key_free(pk);
915                 werr = WERR_INTERNAL_ERROR;
916                 goto done;
917         }
918
919         RSA_returned_bits = BN_num_bits((*rsa)->n);
920         DEBUG(6, ("GnuTLS returned an RSA private key with %d bits\n", RSA_returned_bits));
921
922         if (RSA_returned_bits != bits) {
923                 DEBUG(0, ("GnuTLS unexpectedly returned an RSA private key with %d bits, needed %d\n", RSA_returned_bits, bits));
924                 hx509_private_key_free(pk);
925                 werr = WERR_INTERNAL_ERROR;
926                 goto done;
927         }
928
929         werr = WERR_OK;
930
931 done:
932         if (p0 != NULL) {
933                 memset(p0, 0, len);
934                 TALLOC_FREE(p0);
935         }
936
937         gnutls_x509_privkey_deinit(gtls_key);
938         gnutls_global_deinit();
939         return werr;
940 }
941
942 static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req,
943                                 time_t lifetime, hx509_private_key *private_key,
944                                 hx509_cert *cert, DATA_BLOB *guidblob)
945 {
946         SubjectPublicKeyInfo spki;
947         hx509_name subject = NULL;
948         hx509_ca_tbs tbs;
949         struct heim_bit_string uniqueid;
950         struct heim_integer serialnumber;
951         int ret, i;
952
953         uniqueid.data = talloc_memdup(ctx, guidblob->data, guidblob->length);
954         if (uniqueid.data == NULL) {
955                 return WERR_NOT_ENOUGH_MEMORY;
956         }
957         /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0)
958          * so as 1 byte is 8 bits we need to provision 8 times more space as in the
959          * blob
960          */
961         uniqueid.length = 8 * guidblob->length;
962
963         serialnumber.data = talloc_array(ctx, uint8_t,
964                                             guidblob->length);
965         if (serialnumber.data == NULL) {
966                 talloc_free(uniqueid.data);
967                 return WERR_NOT_ENOUGH_MEMORY;
968         }
969
970         /* Native AD generates certificates with serialnumber in reversed notation */
971         for (i = 0; i < guidblob->length; i++) {
972                 uint8_t *reversed = (uint8_t *)serialnumber.data;
973                 uint8_t *uncrypt = guidblob->data;
974                 reversed[i] = uncrypt[guidblob->length - 1 - i];
975         }
976         serialnumber.length = guidblob->length;
977         serialnumber.negative = 0;
978
979         memset(&spki, 0, sizeof(spki));
980
981         ret = hx509_request_get_name(*hctx, *req, &subject);
982         if (ret !=0) {
983                 goto fail_subject;
984         }
985         ret = hx509_request_get_SubjectPublicKeyInfo(*hctx, *req, &spki);
986         if (ret !=0) {
987                 goto fail_spki;
988         }
989
990         ret = hx509_ca_tbs_init(*hctx, &tbs);
991         if (ret !=0) {
992                 goto fail_tbs;
993         }
994
995         ret = hx509_ca_tbs_set_spki(*hctx, tbs, &spki);
996         if (ret !=0) {
997                 goto fail;
998         }
999         ret = hx509_ca_tbs_set_subject(*hctx, tbs, subject);
1000         if (ret !=0) {
1001                 goto fail;
1002         }
1003         ret = hx509_ca_tbs_set_notAfter_lifetime(*hctx, tbs, lifetime);
1004         if (ret !=0) {
1005                 goto fail;
1006         }
1007         ret = hx509_ca_tbs_set_unique(*hctx, tbs, &uniqueid, &uniqueid);
1008         if (ret !=0) {
1009                 goto fail;
1010         }
1011         ret = hx509_ca_tbs_set_serialnumber(*hctx, tbs, &serialnumber);
1012         if (ret !=0) {
1013                 goto fail;
1014         }
1015         ret = hx509_ca_sign_self(*hctx, tbs, *private_key, cert);
1016         if (ret !=0) {
1017                 goto fail;
1018         }
1019         hx509_name_free(&subject);
1020         free_SubjectPublicKeyInfo(&spki);
1021         hx509_ca_tbs_free(&tbs);
1022
1023         return WERR_OK;
1024
1025 fail:
1026         hx509_ca_tbs_free(&tbs);
1027 fail_tbs:
1028         free_SubjectPublicKeyInfo(&spki);
1029 fail_spki:
1030         hx509_name_free(&subject);
1031 fail_subject:
1032         talloc_free(uniqueid.data);
1033         talloc_free(serialnumber.data);
1034         return WERR_INTERNAL_ERROR;
1035 }
1036
1037 static WERROR create_req(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req,
1038                          hx509_private_key *signer,RSA **rsa, const char *dn)
1039 {
1040         int ret;
1041         SubjectPublicKeyInfo key;
1042
1043         hx509_name name;
1044         WERROR werr;
1045
1046         werr = create_heimdal_rsa_key(ctx, hctx, signer, rsa);
1047         if (!W_ERROR_IS_OK(werr)) {
1048                 return werr;
1049         }
1050
1051         hx509_request_init(*hctx, req);
1052         ret = hx509_parse_name(*hctx, dn, &name);
1053         if (ret != 0) {
1054                 RSA_free(*rsa);
1055                 hx509_private_key_free(signer);
1056                 hx509_request_free(req);
1057                 hx509_name_free(&name);
1058                 return WERR_INTERNAL_ERROR;
1059         }
1060
1061         ret = hx509_request_set_name(*hctx, *req, name);
1062         if (ret != 0) {
1063                 RSA_free(*rsa);
1064                 hx509_private_key_free(signer);
1065                 hx509_request_free(req);
1066                 hx509_name_free(&name);
1067                 return WERR_INTERNAL_ERROR;
1068         }
1069         hx509_name_free(&name);
1070
1071         ret = hx509_private_key2SPKI(*hctx, *signer, &key);
1072         if (ret != 0) {
1073                 RSA_free(*rsa);
1074                 hx509_private_key_free(signer);
1075                 hx509_request_free(req);
1076                 return WERR_INTERNAL_ERROR;
1077         }
1078         ret = hx509_request_set_SubjectPublicKeyInfo(*hctx, *req, &key);
1079         if (ret != 0) {
1080                 RSA_free(*rsa);
1081                 hx509_private_key_free(signer);
1082                 free_SubjectPublicKeyInfo(&key);
1083                 hx509_request_free(req);
1084                 return WERR_INTERNAL_ERROR;
1085         }
1086
1087         free_SubjectPublicKeyInfo(&key);
1088
1089         return WERR_OK;
1090 }
1091
1092 /* Return an error when we fail to generate a certificate */
1093 static WERROR generate_bkrp_cert(TALLOC_CTX *ctx, struct dcesrv_call_state *dce_call, struct ldb_context *ldb_ctx, const char *dn)
1094 {
1095         heim_octet_string data;
1096         WERROR werr;
1097         RSA *rsa;
1098         hx509_context hctx;
1099         hx509_private_key pk;
1100         hx509_request req;
1101         hx509_cert cert;
1102         DATA_BLOB blob;
1103         DATA_BLOB blobkeypair;
1104         DATA_BLOB *tmp;
1105         int ret;
1106         bool ok = true;
1107         struct GUID guid = GUID_random();
1108         NTSTATUS status;
1109         char *secret_name;
1110         struct bkrp_exported_RSA_key_pair keypair;
1111         enum ndr_err_code ndr_err;
1112         uint32_t nb_seconds_validity = 3600 * 24 * 365;
1113
1114         DEBUG(6, ("Trying to generate a certificate\n"));
1115         hx509_context_init(&hctx);
1116         werr = create_req(ctx, &hctx, &req, &pk, &rsa, dn);
1117         if (!W_ERROR_IS_OK(werr)) {
1118                 hx509_context_free(&hctx);
1119                 return werr;
1120         }
1121
1122         status = GUID_to_ndr_blob(&guid, ctx, &blob);
1123         if (!NT_STATUS_IS_OK(status)) {
1124                 hx509_context_free(&hctx);
1125                 hx509_private_key_free(&pk);
1126                 RSA_free(rsa);
1127                 return WERR_INVALID_DATA;
1128         }
1129
1130         werr = self_sign_cert(ctx, &hctx, &req, nb_seconds_validity, &pk, &cert, &blob);
1131         if (!W_ERROR_IS_OK(werr)) {
1132                 hx509_private_key_free(&pk);
1133                 hx509_context_free(&hctx);
1134                 return WERR_INVALID_DATA;
1135         }
1136
1137         ret = hx509_cert_binary(hctx, cert, &data);
1138         if (ret !=0) {
1139                 hx509_cert_free(cert);
1140                 hx509_private_key_free(&pk);
1141                 hx509_context_free(&hctx);
1142                 return WERR_INVALID_DATA;
1143         }
1144
1145         keypair.cert.data = talloc_memdup(ctx, data.data, data.length);
1146         keypair.cert.length = data.length;
1147
1148         /*
1149          * Heimdal's bignum are big endian and the
1150          * structure expect it to be in little endian
1151          * so we reverse the buffer to make it work
1152          */
1153         tmp = reverse_and_get_blob(ctx, rsa->e);
1154         if (tmp == NULL) {
1155                 ok = false;
1156         } else {
1157                 keypair.public_exponent = *tmp;
1158                 SMB_ASSERT(tmp->length <= 4);
1159                 /*
1160                  * The value is now in little endian but if can happen that the length is
1161                  * less than 4 bytes.
1162                  * So if we have less than 4 bytes we pad with zeros so that it correctly
1163                  * fit into the structure.
1164                  */
1165                 if (tmp->length < 4) {
1166                         /*
1167                          * We need the expo to fit 4 bytes
1168                          */
1169                         keypair.public_exponent.data = talloc_zero_array(ctx, uint8_t, 4);
1170                         memcpy(keypair.public_exponent.data, tmp->data, tmp->length);
1171                         keypair.public_exponent.length = 4;
1172                 }
1173         }
1174
1175         tmp = reverse_and_get_blob(ctx,rsa->d);
1176         if (tmp == NULL) {
1177                 ok = false;
1178         } else {
1179                 keypair.private_exponent = *tmp;
1180         }
1181
1182         tmp = reverse_and_get_blob(ctx,rsa->n);
1183         if (tmp == NULL) {
1184                 ok = false;
1185         } else {
1186                 keypair.modulus = *tmp;
1187         }
1188
1189         tmp = reverse_and_get_blob(ctx,rsa->p);
1190         if (tmp == NULL) {
1191                 ok = false;
1192         } else {
1193                 keypair.prime1 = *tmp;
1194         }
1195
1196         tmp = reverse_and_get_blob(ctx,rsa->q);
1197         if (tmp == NULL) {
1198                 ok = false;
1199         } else {
1200                 keypair.prime2 = *tmp;
1201         }
1202
1203         tmp = reverse_and_get_blob(ctx,rsa->dmp1);
1204         if (tmp == NULL) {
1205                 ok = false;
1206         } else {
1207                 keypair.exponent1 = *tmp;
1208         }
1209
1210         tmp = reverse_and_get_blob(ctx,rsa->dmq1);
1211         if (tmp == NULL) {
1212                 ok = false;
1213         } else {
1214                 keypair.exponent2 = *tmp;
1215         }
1216
1217         tmp = reverse_and_get_blob(ctx,rsa->iqmp);
1218         if (tmp == NULL) {
1219                 ok = false;
1220         } else {
1221                 keypair.coefficient = *tmp;
1222         }
1223
1224         /* One of the keypair allocation was wrong */
1225         if (ok == false) {
1226                 der_free_octet_string(&data);
1227                 hx509_cert_free(cert);
1228                 hx509_private_key_free(&pk);
1229                 hx509_context_free(&hctx);
1230                 RSA_free(rsa);
1231                 return WERR_INVALID_DATA;
1232         }
1233         keypair.certificate_len = keypair.cert.length;
1234         ndr_err = ndr_push_struct_blob(&blobkeypair, ctx, &keypair, (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair);
1235         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1236                 der_free_octet_string(&data);
1237                 hx509_cert_free(cert);
1238                 hx509_private_key_free(&pk);
1239                 hx509_context_free(&hctx);
1240                 RSA_free(rsa);
1241                 return WERR_INVALID_DATA;
1242         }
1243
1244         secret_name = talloc_asprintf(ctx, "BCKUPKEY_%s", GUID_string(ctx, &guid));
1245         if (secret_name == NULL) {
1246                 der_free_octet_string(&data);
1247                 hx509_cert_free(cert);
1248                 hx509_private_key_free(&pk);
1249                 hx509_context_free(&hctx);
1250                 RSA_free(rsa);
1251                 return WERR_OUTOFMEMORY;
1252         }
1253
1254         status = set_lsa_secret(ctx, ldb_ctx, secret_name, &blobkeypair);
1255         if (!NT_STATUS_IS_OK(status)) {
1256                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1257         }
1258         talloc_free(secret_name);
1259
1260         GUID_to_ndr_blob(&guid, ctx, &blob);
1261         status = set_lsa_secret(ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob);
1262         if (!NT_STATUS_IS_OK(status)) {
1263                 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
1264         }
1265
1266         der_free_octet_string(&data);
1267         hx509_cert_free(cert);
1268         hx509_private_key_free(&pk);
1269         hx509_context_free(&hctx);
1270         RSA_free(rsa);
1271         return WERR_OK;
1272 }
1273
1274 static WERROR bkrp_retrieve_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1275                                             struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
1276 {
1277         struct GUID guid;
1278         char *guid_string;
1279         DATA_BLOB lsa_secret;
1280         enum ndr_err_code ndr_err;
1281         NTSTATUS status;
1282
1283         /*
1284          * here we basicaly need to return our certificate
1285          * search for lsa secret BCKUPKEY_PREFERRED first
1286          */
1287
1288         status = get_lsa_secret(mem_ctx,
1289                                 ldb_ctx,
1290                                 "BCKUPKEY_PREFERRED",
1291                                 &lsa_secret);
1292         if (NT_STATUS_EQUAL(status, NT_STATUS_RESOURCE_NAME_NOT_FOUND)) {
1293                 /* Ok we can be in this case if there was no certs */
1294                 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1295                 char *dn = talloc_asprintf(mem_ctx, "CN=%s",
1296                                            lpcfg_realm(lp_ctx));
1297
1298                 WERROR werr =  generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn);
1299                 if (!W_ERROR_IS_OK(werr)) {
1300                         return WERR_INVALID_PARAMETER;
1301                 }
1302                 status = get_lsa_secret(mem_ctx,
1303                                         ldb_ctx,
1304                                         "BCKUPKEY_PREFERRED",
1305                                         &lsa_secret);
1306
1307                 if (!NT_STATUS_IS_OK(status)) {
1308                         /* Ok we really don't manage to get this certs ...*/
1309                         DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
1310                         return WERR_FILE_NOT_FOUND;
1311                 }
1312         } else if (!NT_STATUS_IS_OK(status)) {
1313                 return WERR_INTERNAL_ERROR;
1314         }
1315
1316         if (lsa_secret.length == 0) {
1317                 DEBUG(1, ("No secret in BCKUPKEY_PREFERRED, are we an undetected RODC?\n"));
1318                 return WERR_INTERNAL_ERROR;
1319         } else {
1320                 char *cert_secret_name;
1321
1322                 status = GUID_from_ndr_blob(&lsa_secret, &guid);
1323                 if (!NT_STATUS_IS_OK(status)) {
1324                         return WERR_FILE_NOT_FOUND;
1325                 }
1326
1327                 guid_string = GUID_string(mem_ctx, &guid);
1328                 if (guid_string == NULL) {
1329                         /* We return file not found because the client
1330                          * expect this error
1331                          */
1332                         return WERR_FILE_NOT_FOUND;
1333                 }
1334
1335                 cert_secret_name = talloc_asprintf(mem_ctx,
1336                                                         "BCKUPKEY_%s",
1337                                                         guid_string);
1338                 status = get_lsa_secret(mem_ctx,
1339                                         ldb_ctx,
1340                                         cert_secret_name,
1341                                         &lsa_secret);
1342                 if (!NT_STATUS_IS_OK(status)) {
1343                         return WERR_FILE_NOT_FOUND;
1344                 }
1345
1346                 if (lsa_secret.length != 0) {
1347                         struct bkrp_exported_RSA_key_pair keypair;
1348                         ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair,
1349                                         (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
1350                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1351                                 return WERR_FILE_NOT_FOUND;
1352                         }
1353                         *(r->out.data_out_len) = keypair.cert.length;
1354                         *(r->out.data_out) = talloc_memdup(mem_ctx, keypair.cert.data, keypair.cert.length);
1355                         W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
1356                         return WERR_OK;
1357                 } else {
1358                         DEBUG(1, ("No or broken secret called %s\n", cert_secret_name));
1359                         return WERR_INTERNAL_ERROR;
1360                 }
1361         }
1362
1363         return WERR_NOT_SUPPORTED;
1364 }
1365
1366 static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context *ldb_ctx)
1367 {
1368         struct GUID guid = GUID_random();
1369         enum ndr_err_code ndr_err;
1370         DATA_BLOB blob_wrap_key, guid_blob;
1371         struct bkrp_dc_serverwrap_key wrap_key;
1372         NTSTATUS status;
1373         char *secret_name;
1374         TALLOC_CTX *frame = talloc_stackframe();
1375
1376         generate_random_buffer(wrap_key.key, sizeof(wrap_key.key));
1377
1378         ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key);
1379         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1380                 TALLOC_FREE(frame);
1381                 return WERR_INVALID_DATA;
1382         }
1383
1384         secret_name = talloc_asprintf(frame, "BCKUPKEY_%s", GUID_string(ctx, &guid));
1385         if (secret_name == NULL) {
1386                 TALLOC_FREE(frame);
1387                 return WERR_NOT_ENOUGH_MEMORY;
1388         }
1389
1390         status = set_lsa_secret(frame, ldb_ctx, secret_name, &blob_wrap_key);
1391         if (!NT_STATUS_IS_OK(status)) {
1392                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1393                 TALLOC_FREE(frame);
1394                 return WERR_INTERNAL_ERROR;
1395         }
1396
1397         status = GUID_to_ndr_blob(&guid, frame, &guid_blob);
1398         if (!NT_STATUS_IS_OK(status)) {
1399                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1400                 TALLOC_FREE(frame);
1401         }
1402
1403         status = set_lsa_secret(frame, ldb_ctx, "BCKUPKEY_P", &guid_blob);
1404         if (!NT_STATUS_IS_OK(status)) {
1405                 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1406                 TALLOC_FREE(frame);
1407                 return WERR_INTERNAL_ERROR;
1408         }
1409
1410         TALLOC_FREE(frame);
1411
1412         return WERR_OK;
1413 }
1414
1415 /*
1416  * Find the specified decryption keys from the LSA secrets store as
1417  * G$BCKUPKEY_keyGuidString.
1418  */
1419
1420 static WERROR bkrp_do_retrieve_server_wrap_key(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx,
1421                                                struct bkrp_dc_serverwrap_key *server_key,
1422                                                struct GUID *guid)
1423 {
1424         NTSTATUS status;
1425         DATA_BLOB lsa_secret;
1426         char *secret_name;
1427         char *guid_string;
1428         enum ndr_err_code ndr_err;
1429
1430         guid_string = GUID_string(mem_ctx, guid);
1431         if (guid_string == NULL) {
1432                 /* We return file not found because the client
1433                  * expect this error
1434                  */
1435                 return WERR_FILE_NOT_FOUND;
1436         }
1437
1438         secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", guid_string);
1439         if (secret_name == NULL) {
1440                 return WERR_NOT_ENOUGH_MEMORY;
1441         }
1442
1443         status = get_lsa_secret(mem_ctx, ldb_ctx, secret_name, &lsa_secret);
1444         if (!NT_STATUS_IS_OK(status)) {
1445                 DEBUG(10, ("Error while fetching secret %s\n", secret_name));
1446                 return WERR_INVALID_DATA;
1447         }
1448         if (lsa_secret.length == 0) {
1449                 /* RODC case, we do not have secrets locally */
1450                 DEBUG(1, ("Unable to fetch value for secret %s, are we an undetected RODC?\n",
1451                           secret_name));
1452                 return WERR_INTERNAL_ERROR;
1453         }
1454         ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, server_key,
1455                                        (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key);
1456         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1457                 DEBUG(2, ("Unable to parse the ndr encoded server wrap key %s\n", secret_name));
1458                 return WERR_INVALID_DATA;
1459         }
1460
1461         return WERR_OK;
1462 }
1463
1464 /*
1465  * Find the current, preferred ServerWrap Key by looking at
1466  * G$BCKUPKEY_P in the LSA secrets store.
1467  *
1468  * Then find the current decryption keys from the LSA secrets store as
1469  * G$BCKUPKEY_keyGuidString.
1470  */
1471
1472 static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx,
1473                                                        struct ldb_context *ldb_ctx,
1474                                                        struct bkrp_dc_serverwrap_key *server_key,
1475                                                        struct GUID *returned_guid)
1476 {
1477         NTSTATUS status;
1478         DATA_BLOB guid_binary;
1479
1480         status = get_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_P", &guid_binary);
1481         if (!NT_STATUS_IS_OK(status)) {
1482                 DEBUG(10, ("Error while fetching secret BCKUPKEY_P to find current GUID\n"));
1483                 return WERR_FILE_NOT_FOUND;
1484         } else if (guid_binary.length == 0) {
1485                 /* RODC case, we do not have secrets locally */
1486                 DEBUG(1, ("Unable to fetch value for secret BCKUPKEY_P, are we an undetected RODC?\n"));
1487                 return WERR_INTERNAL_ERROR;
1488         }
1489
1490         status = GUID_from_ndr_blob(&guid_binary, returned_guid);
1491         if (!NT_STATUS_IS_OK(status)) {
1492                 return WERR_FILE_NOT_FOUND;
1493         }
1494
1495         return bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx,
1496                                                 server_key, returned_guid);
1497 }
1498
1499 static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1500                                             struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1501 {
1502         struct auth_session_info *session_info =
1503                 dcesrv_call_session_info(dce_call);
1504         WERROR werr;
1505         struct bkrp_server_side_wrapped decrypt_request;
1506         DATA_BLOB sid_blob, encrypted_blob, symkey_blob;
1507         DATA_BLOB blob;
1508         enum ndr_err_code ndr_err;
1509         struct bkrp_dc_serverwrap_key server_key;
1510         struct bkrp_rc4encryptedpayload rc4payload;
1511         struct dom_sid *caller_sid;
1512         uint8_t symkey[20]; /* SHA-1 hash len */
1513         uint8_t mackey[20]; /* SHA-1 hash len */
1514         uint8_t mac[20]; /* SHA-1 hash len */
1515         unsigned int hash_len;
1516         HMAC_CTX ctx;
1517
1518         blob.data = r->in.data_in;
1519         blob.length = r->in.data_in_len;
1520
1521         if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
1522                 return WERR_INVALID_PARAMETER;
1523         }
1524
1525         ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &decrypt_request,
1526                                            (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
1527         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1528                 return WERR_INVALID_PARAMETER;
1529         }
1530
1531         if (decrypt_request.magic != BACKUPKEY_SERVER_WRAP_VERSION) {
1532                 return WERR_INVALID_PARAMETER;
1533         }
1534
1535         werr = bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, &server_key,
1536                                                 &decrypt_request.guid);
1537         if (!W_ERROR_IS_OK(werr)) {
1538                 return werr;
1539         }
1540
1541         dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
1542
1543         dump_data_pw("r2: \n", decrypt_request.r2, sizeof(decrypt_request.r2));
1544
1545         /*
1546          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1547          * BACKUPKEY_BACKUP_GUID, it really is the whole key
1548          */
1549         HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key),
1550              decrypt_request.r2, sizeof(decrypt_request.r2),
1551              symkey, &hash_len);
1552
1553         dump_data_pw("symkey: \n", symkey, hash_len);
1554
1555         /* rc4 decrypt sid and secret using sym key */
1556         symkey_blob = data_blob_const(symkey, sizeof(symkey));
1557
1558         encrypted_blob = data_blob_const(decrypt_request.rc4encryptedpayload,
1559                                          decrypt_request.ciphertext_length);
1560
1561         arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob);
1562
1563         ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload,
1564                                            (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload);
1565         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1566                 return WERR_INVALID_PARAMETER;
1567         }
1568
1569         if (decrypt_request.payload_length != rc4payload.secret_data.length) {
1570                 return WERR_INVALID_PARAMETER;
1571         }
1572
1573         dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
1574
1575         /*
1576          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1577          * BACKUPKEY_BACKUP_GUID, it really is the whole key
1578          */
1579         HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key),
1580              rc4payload.r3, sizeof(rc4payload.r3),
1581              mackey, &hash_len);
1582
1583         dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1584
1585         ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, &rc4payload.sid,
1586                                        (ndr_push_flags_fn_t)ndr_push_dom_sid);
1587         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1588                 return WERR_INTERNAL_ERROR;
1589         }
1590
1591         HMAC_CTX_init(&ctx);
1592         HMAC_Init_ex(&ctx, mackey, hash_len, EVP_sha1(), NULL);
1593         /* SID field */
1594         HMAC_Update(&ctx, sid_blob.data, sid_blob.length);
1595         /* Secret field */
1596         HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length);
1597         HMAC_Final(&ctx, mac, &hash_len);
1598         HMAC_CTX_cleanup(&ctx);
1599
1600         dump_data_pw("mac: \n", mac, sizeof(mac));
1601         dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1602
1603         if (memcmp(mac, rc4payload.mac, sizeof(mac)) != 0) {
1604                 return WERR_INVALID_ACCESS;
1605         }
1606
1607         caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
1608
1609         if (!dom_sid_equal(&rc4payload.sid, caller_sid)) {
1610                 return WERR_INVALID_ACCESS;
1611         }
1612
1613         *(r->out.data_out) = rc4payload.secret_data.data;
1614         *(r->out.data_out_len) = rc4payload.secret_data.length;
1615
1616         return WERR_OK;
1617 }
1618
1619 /*
1620  * For BACKUPKEY_RESTORE_GUID we need to check the first 4 bytes to
1621  * determine what type of restore is wanted.
1622  *
1623  * See MS-BKRP 3.1.4.1.4 BACKUPKEY_RESTORE_GUID point 1.
1624  */
1625
1626 static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1627                                         struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
1628 {
1629         if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
1630                 return WERR_INVALID_PARAMETER;
1631         }
1632
1633         if (IVAL(r->in.data_in, 0) == BACKUPKEY_SERVER_WRAP_VERSION) {
1634                 return bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1635         }
1636
1637         return bkrp_client_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1638 }
1639
1640 /*
1641  * We have some data, such as saved website or IMAP passwords that the
1642  * client would like to put into the profile on-disk.  This needs to
1643  * be encrypted.  This version gives the server the data over the
1644  * network (protected only by the negotiated transport encryption),
1645  * and asks that it be encrypted and returned for long-term storage.
1646  *
1647  * The data is NOT stored in the LSA, but a key to encrypt the data
1648  * will be stored.  There is only one active encryption key per domain,
1649  * it is pointed at with G$BCKUPKEY_P in the LSA secrets store.
1650  *
1651  * The potentially multiple valid decryptiong keys (and the encryption
1652  * key) are in turn stored in the LSA secrets store as
1653  * G$BCKUPKEY_keyGuidString.
1654  *
1655  */
1656
1657 static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1658                                             struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1659 {
1660         struct auth_session_info *session_info =
1661                 dcesrv_call_session_info(dce_call);
1662         DATA_BLOB sid_blob, encrypted_blob, symkey_blob, server_wrapped_blob;
1663         WERROR werr;
1664         struct dom_sid *caller_sid;
1665         uint8_t symkey[20]; /* SHA-1 hash len */
1666         uint8_t mackey[20]; /* SHA-1 hash len */
1667         unsigned int hash_len;
1668         struct bkrp_rc4encryptedpayload rc4payload;
1669         HMAC_CTX ctx;
1670         struct bkrp_dc_serverwrap_key server_key;
1671         enum ndr_err_code ndr_err;
1672         struct bkrp_server_side_wrapped server_side_wrapped;
1673         struct GUID guid;
1674
1675         if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
1676                 return WERR_INVALID_PARAMETER;
1677         }
1678
1679         werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
1680                                                         ldb_ctx, &server_key,
1681                                                         &guid);
1682
1683         if (!W_ERROR_IS_OK(werr)) {
1684                 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1685                         /* Generate the server wrap key since one wasn't found */
1686                         werr =  generate_bkrp_server_wrap_key(mem_ctx,
1687                                                               ldb_ctx);
1688                         if (!W_ERROR_IS_OK(werr)) {
1689                                 return WERR_INVALID_PARAMETER;
1690                         }
1691                         werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
1692                                                                         ldb_ctx,
1693                                                                         &server_key,
1694                                                                         &guid);
1695
1696                         if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1697                                 /* Ok we really don't manage to get this secret ...*/
1698                                 return WERR_FILE_NOT_FOUND;
1699                         }
1700                 } else {
1701                         /* In theory we should NEVER reach this point as it
1702                            should only appear in a rodc server */
1703                         /* we do not have the real secret attribute */
1704                         return WERR_INVALID_PARAMETER;
1705                 }
1706         }
1707
1708         caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
1709
1710         dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
1711
1712         /*
1713          * This is the key derivation step, so that the HMAC and RC4
1714          * operations over the user-supplied data are not able to
1715          * disclose the master key.  By using random data, the symkey
1716          * and mackey values are unique for this operation, and
1717          * discovering these (by reversing the RC4 over the
1718          * attacker-controlled data) does not return something able to
1719          * be used to decyrpt the encrypted data of other users
1720          */
1721         generate_random_buffer(server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
1722
1723         dump_data_pw("r2: \n", server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
1724
1725         generate_random_buffer(rc4payload.r3, sizeof(rc4payload.r3));
1726
1727         dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
1728
1729
1730         /*
1731          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1732          * BACKUPKEY_BACKUP_GUID, it really is the whole key
1733          */
1734         HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key),
1735              server_side_wrapped.r2, sizeof(server_side_wrapped.r2),
1736              symkey, &hash_len);
1737
1738         dump_data_pw("symkey: \n", symkey, hash_len);
1739
1740         /*
1741          * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1742          * BACKUPKEY_BACKUP_GUID, it really is the whole key
1743          */
1744         HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key),
1745              rc4payload.r3, sizeof(rc4payload.r3),
1746              mackey, &hash_len);
1747
1748         dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1749
1750         ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, caller_sid,
1751                                        (ndr_push_flags_fn_t)ndr_push_dom_sid);
1752         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1753                 return WERR_INTERNAL_ERROR;
1754         }
1755
1756         rc4payload.secret_data.data = r->in.data_in;
1757         rc4payload.secret_data.length = r->in.data_in_len;
1758
1759         HMAC_CTX_init(&ctx);
1760         HMAC_Init_ex(&ctx, mackey, 20, EVP_sha1(), NULL);
1761         /* SID field */
1762         HMAC_Update(&ctx, sid_blob.data, sid_blob.length);
1763         /* Secret field */
1764         HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length);
1765         HMAC_Final(&ctx, rc4payload.mac, &hash_len);
1766         HMAC_CTX_cleanup(&ctx);
1767
1768         dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1769
1770         rc4payload.sid = *caller_sid;
1771
1772         ndr_err = ndr_push_struct_blob(&encrypted_blob, mem_ctx, &rc4payload,
1773                                        (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload);
1774         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1775                 return WERR_INTERNAL_ERROR;
1776         }
1777
1778         /* rc4 encrypt sid and secret using sym key */
1779         symkey_blob = data_blob_const(symkey, sizeof(symkey));
1780         arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob);
1781
1782         /* create server wrap structure */
1783
1784         server_side_wrapped.payload_length = rc4payload.secret_data.length;
1785         server_side_wrapped.ciphertext_length = encrypted_blob.length;
1786         server_side_wrapped.guid = guid;
1787         server_side_wrapped.rc4encryptedpayload = encrypted_blob.data;
1788
1789         ndr_err = ndr_push_struct_blob(&server_wrapped_blob, mem_ctx, &server_side_wrapped,
1790                                        (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
1791         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1792                 return WERR_INTERNAL_ERROR;
1793         }
1794
1795         *(r->out.data_out) = server_wrapped_blob.data;
1796         *(r->out.data_out_len) = server_wrapped_blob.length;
1797
1798         return WERR_OK;
1799 }
1800
1801 static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call,
1802                                     TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r)
1803 {
1804         WERROR error = WERR_INVALID_PARAMETER;
1805         struct ldb_context *ldb_ctx;
1806         bool is_rodc;
1807         const char *addr = "unknown";
1808         /* At which level we start to add more debug of what is done in the protocol */
1809         const int debuglevel = 4;
1810
1811         if (DEBUGLVL(debuglevel)) {
1812                 const struct tsocket_address *remote_address;
1813                 remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
1814                 if (tsocket_address_is_inet(remote_address, "ip")) {
1815                         addr = tsocket_address_inet_addr_string(remote_address, mem_ctx);
1816                         W_ERROR_HAVE_NO_MEMORY(addr);
1817                 }
1818         }
1819
1820         if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) {
1821                 return WERR_NOT_SUPPORTED;
1822         }
1823
1824         /*
1825          * Save the current remote session details so they can used by the
1826          * audit logging module. This allows the audit logging to report the
1827          * remote users details, rather than the system users details.
1828          */
1829         ldb_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
1830         if (samdb_rodc(ldb_ctx, &is_rodc) != LDB_SUCCESS) {
1831                 talloc_unlink(mem_ctx, ldb_ctx);
1832                 return WERR_INVALID_PARAMETER;
1833         }
1834
1835         if (!is_rodc) {
1836                 if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1837                         BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) {
1838                         DEBUG(debuglevel, ("Client %s requested to decrypt a wrapped secret\n", addr));
1839                         error = bkrp_generic_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1840                 }
1841
1842                 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1843                         BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) {
1844                         DEBUG(debuglevel, ("Client %s requested certificate for client wrapped secret\n", addr));
1845                         error = bkrp_retrieve_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx);
1846                 }
1847
1848                 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1849                         BACKUPKEY_RESTORE_GUID_WIN2K, strlen(BACKUPKEY_RESTORE_GUID_WIN2K)) == 0) {
1850                         DEBUG(debuglevel, ("Client %s requested to decrypt a server side wrapped secret\n", addr));
1851                         error = bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1852                 }
1853
1854                 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1855                         BACKUPKEY_BACKUP_GUID, strlen(BACKUPKEY_BACKUP_GUID)) == 0) {
1856                         DEBUG(debuglevel, ("Client %s requested a server wrapped secret\n", addr));
1857                         error = bkrp_server_wrap_encrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1858                 }
1859         }
1860         /*else: I am a RODC so I don't handle backup key protocol */
1861
1862         talloc_unlink(mem_ctx, ldb_ctx);
1863         return error;
1864 }
1865
1866 /* include the generated boilerplate */
1867 #include "librpc/gen_ndr/ndr_backupkey_s.c"