The branch, master has been updated
       via  33b55227db8 s4:kdc Support for key trust authentication
       via  4ffb578aa74 s4:kdc:sdb: Add support for key trust public keys
       via  353c5bb86a7 s4:kdc: Fix clang-tidy error in db-glue.c
       via  0d31b2b28b3 librpc: keycredlink support X509 public keys
       via  93eecdddfe5 librpc/idl: Add idl for tpm20_rsakey_blob
       via  f9533d5c776 librpc/idl: update keycredlink comments
       via  acd0fccfdd1 librpc/idl: Add idl for BCRYPT_RSAKEY_BLOB
      from  7c7455926d9 ctdb-tests: Fix CID 1659221 - Error handling issues 
(CHECKED_RETURN)

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 33b55227db888acf70db9ff44c385a294e07ce36
Author: Gary Lockyer <[email protected]>
Date:   Fri Jul 25 13:22:27 2025 +1200

    s4:kdc Support for key trust authentication
    
    Extract the public kes from msDS-KeyCredentialLink and populate the sdb
    structure.  These values can then be passed to Kergeros to allow key
    trust authentication.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>
    
    Autobuild-User(master): Douglas Bagnall <[email protected]>
    Autobuild-Date(master): Tue Jul 29 05:31:10 UTC 2025 on atb-devel-224

commit 4ffb578aa749a5ac56b0b4c5258aa4618092bfcf
Author: Gary Lockyer <[email protected]>
Date:   Thu Jul 17 14:12:08 2025 +1200

    s4:kdc:sdb: Add support for key trust public keys
    
    Add public keys to the sdb entry to allow them to be passed to Kerberos
    for key trust authentication.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 353c5bb86a7492515d5a3b226565a7e641ee64a2
Author: Gary Lockyer <[email protected]>
Date:   Thu Jul 17 11:47:39 2025 +1200

    s4:kdc: Fix clang-tidy error in db-glue.c
    
    ../../source4/kdc/db-glue.c:968:14: warning: Access to field 'kvno' results 
in a dereference of a null pointer (loaded from variable 'entry') 
[clang-analyzer-core.NullDereference]
      968 |         entry->kvno = returned_kvno;
          |         ~~~~~       ^
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 0d31b2b28b3849b4954416f45fc39b4009bcbea8
Author: Gary Lockyer <[email protected]>
Date:   Fri Jul 11 13:41:42 2025 +1200

    librpc: keycredlink support X509 public keys
    
    Add support for X509 encoded public keys in msDSKeyCredentialLink
    KeyMaterial.
    
    Note: Only RSA public keys are supported.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 93eecdddfe5f192fa4c4463d3c9a25ab9160bd6a
Author: Gary Lockyer <[email protected]>
Date:   Tue Jul 1 09:43:07 2025 +1200

    librpc/idl: Add idl for tpm20_rsakey_blob
    
    Idl and tests for TPM20_RSAKEY_BLOB, one of the possible encoding of
    msDSKeyCredentialLink KeyMaterial
    Derived from:
        https://dox.ipxe.org/Tpm20_8h_source.html#l00164
        
https://stackoverflow.com/questions/78958315/cannot-parse-tpm2-0-public-key
    
    Note: this is a greatly simplified implementation that only handles TPM
          version 2, RSA public keys.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit f9533d5c7764bea42296aca806daaf9a4a2385a2
Author: Gary Lockyer <[email protected]>
Date:   Tue Jun 24 10:45:58 2025 +1200

    librpc/idl: update keycredlink comments
    
    Replace // comments with /* */ and document the KeyId and KeyHash
    elements.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit acd0fccfdd10dab245595fbfb9934c0674ed9e76
Author: Gary Lockyer <[email protected]>
Date:   Mon Jun 23 15:01:37 2025 +1200

    librpc/idl: Add idl for BCRYPT_RSAKEY_BLOB
    
    Idl and tests for BCRYPT_RSAKEY_BLOB
    See https://learn.microsoft.com/en-us/windows/win32/api/
                bcrypt/ns-bcrypt-bcrypt_rsakey_blob
    
    This is one of the encodings of msDSKeyCredentialLink KeyMaterial when
    KeyUsage is KEY_USAGE_NGC. As there appears to be no official
    documentation on the contents of KeyMaterial have based this on.
    
        
https://github.com/p0dalirius/pydsinternals/blob/271dd969e07a8939044bfc498d94443082ec6fa9/
                dsinternals/common/data/hello/KeyCredential.py#L75-L92
    
    Note: only RSA public keys are handled
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/bcrypt_rsakey_blob.idl         |   43 ++
 librpc/idl/keycredlink.idl                |   58 +-
 librpc/idl/tpm20_rsakey_blob.idl          |  126 ++++
 librpc/idl/wscript_build                  |    2 +
 librpc/ndr/ndr_keycredlink.c              |  559 +++++++++++++++
 librpc/wscript_build                      |   12 +-
 python/samba/tests/bcrypt_rsakey_blob.py  |  221 ++++++
 python/samba/tests/key_credential_link.py |  232 +++++++
 python/samba/tests/tpm20_rsakey_blob.py   |  130 ++++
 selftest/tests.py                         |    5 +
 source4/auth/sam.c                        |    4 +-
 source4/kdc/db-glue.c                     |  248 +++++++
 source4/kdc/sdb.c                         |   41 +-
 source4/kdc/sdb.h                         |   14 +
 source4/kdc/tests/db-glue-test.c          | 1054 +++++++++++++++++++++++++++++
 source4/kdc/wscript_build                 |   12 +
 source4/librpc/wscript_build              |   16 +
 17 files changed, 2763 insertions(+), 14 deletions(-)
 create mode 100644 librpc/idl/bcrypt_rsakey_blob.idl
 create mode 100644 librpc/idl/tpm20_rsakey_blob.idl
 create mode 100755 python/samba/tests/bcrypt_rsakey_blob.py
 create mode 100755 python/samba/tests/tpm20_rsakey_blob.py
 create mode 100644 source4/kdc/tests/db-glue-test.c


Changeset truncated at 500 lines:

diff --git a/librpc/idl/bcrypt_rsakey_blob.idl 
b/librpc/idl/bcrypt_rsakey_blob.idl
new file mode 100644
index 00000000000..fd5f6134e34
--- /dev/null
+++ b/librpc/idl/bcrypt_rsakey_blob.idl
@@ -0,0 +1,43 @@
+/*
+   Definitions for packing and unpacking of BCRYPT_RSAPUBLIC_BLOB
+   structures, derived from
+     https://learn.microsoft.com/en-us/windows/win32/api/
+             bcrypt/ns-bcrypt-bcrypt_rsakey_blob
+
+   Note: - Currently only handles RSA public keys
+*/
+
+#include "idl_types.h"
+
+[
+  pointer_default(unique)
+]
+interface bcrypt_rsakey_blob
+{
+       const uint32 BCRYPT_RSAPUBLIC_MAGIC      = 0x31415352;  /* RSA1 */
+
+       /* Public structures. */
+       typedef [public] struct {
+               /* Currently only handle RSA Public Key blobs */
+               [value(0x31415352), range(0x31415352, 0x31415352)]
+                       uint32 magic; /* RSA1 */
+               uint32 bit_length;
+               /*
+                * As of Windows 10 version 1903, public exponents larger
+                * than (2^64 - 1) are no longer supported.
+                */
+               [range(0x0,0x8)] uint32 public_exponent_len;
+               uint32 modulus_len;
+               /*
+                * We're only supporting public keys, so the private
+                * key prime lengths should be zero
+                */
+               [value(0), range(0x0,0x0)] uint32 prime1_len_unused;
+               [value(0), range(0x0,0x0)] uint32 prime2_len_unused;
+               /*
+                * The exponent and modulus are big-endian
+                */
+               uint8 public_exponent[public_exponent_len];
+               uint8 modulus[modulus_len];
+       } BCRYPT_RSAPUBLIC_BLOB;
+}
diff --git a/librpc/idl/keycredlink.idl b/librpc/idl/keycredlink.idl
index 6492df522a1..7190c958652 100644
--- a/librpc/idl/keycredlink.idl
+++ b/librpc/idl/keycredlink.idl
@@ -32,6 +32,13 @@ interface keycredlink
 
        typedef [enum8bit, public] enum {
                KEY_USAGE_NGC  = 0x01,
+                       /*
+                       * KeyMaterial is a 2048 bit RSA (RFC8017) public key
+                       * encoded as a
+                       *   BCRYPT_RSAKEY_BLOB, see bcrypt_rsakey_blob.idl
+                       *   TPM20_RSAKEY_BLOB, see tpm20_rsakey_blob.idl
+                       *   X509 public key
+                       */
                KEY_USAGE_FIDO = 0x02,
                KEY_USAGE_FEK  = 0x03
        } KEYCREDENTIALLINK_ENTRY_KeyUsage;
@@ -51,19 +58,23 @@ interface keycredlink
        } CUSTOM_KEY_INFO_Flags;
 
        typedef [enum8bit, public] enum {
-               Unspecified = 0x00,    // No volume specified
-                                      // defined as None in the docs but this
-                                      // causes issues in the python bindings
-               OSV  = 0x01,    // Operating system volume
-               FDV  = 0x02,    // Fixed data volume
-               RDV  = 0x03     // Removable data volume
+               Unspecified = 0x00,    /*
+                                       * No volume specified
+                                       * defined as None in the docs but this
+                                       * causes issues in the python bindings
+                                       */
+               OSV  = 0x01,    /* Operating system volume */
+               FDV  = 0x02,    /* Fixed data volume       */
+               RDV  = 0x03     /* Removable data volume   */
        } CUSTOM_KEY_INFO_VolType;
 
        typedef [enum8bit, public] enum {
-               Unsupported = 0x00,    // Notification is not supported
-                                      // defined as None in the docs but this
-                                      // causes issues in the python bindings
-               Supported   = 0x01     // Notification is supported
+               Unsupported = 0x00,    /*
+                                       * Notification is not supported
+                                       * defined as None in the docs but this
+                                       * causes issues in the python bindings
+                                       */
+               Supported   = 0x01     /* Notification is supported */
        } CUSTOM_KEY_INFO_SupportsNotification;
 
        typedef [enum8bit, public] enum {
@@ -130,16 +141,26 @@ interface keycredlink
                 flag(NDR_NOALIGN)]
        union {
        [case(KeyID)]
+               /*
+                * SHA-256 hash of the KeyMaterial
+                */
                uint8 keyId[32];
        [case(KeyHash)]
+               /*
+                * SHA-256 hash of all entries following this entry
+                */
                uint8 keyHash[32];
        [case(KeyUsage)]
                KEYCREDENTIALLINK_ENTRY_KeyUsage keyUsage;
        [case(KeySource), value(KEY_SOURCE_AD)]
                KEYCREDENTIALLINK_ENTRY_KeySource keySource;
+               /*
+                * Currently treating Key Material as an opaque binary blob
+                * But if needed it can be partially decoded with
+                * ndr_pull_KeyMaterialInternal
+                */
        [case(KeyMaterial)] [flag(NDR_REMAINING)]
                DATA_BLOB keyMaterial;
-               /* Currently treating Key Material as an opaque binary blob */
        [case(DeviceId)]
                uint8 deviceId[16];
        [case(CustomKeyInformation)]
@@ -164,4 +185,19 @@ interface keycredlink
                uint32 count;
                KEYCREDENTIALLINK_ENTRY entries[count];
        } KEYCREDENTIALLINK_BLOB;
+
+       /* Internal representation of KeyMaterial, that
+        *   - BCRYPT_RSAKEY_BLOB
+        *   - TPM20_RSAKEY_BLOB
+        *   - X509 encoded
+        * public keys are converted to.
+        *
+        * Note: that push is NOT implemented, and currently returns
+        * NDR_ERR_VALIDATE.
+        */
+       typedef [public, nopull, nopush] struct {
+               uint16 bit_size;
+               DATA_BLOB modulus;
+               DATA_BLOB exponent;
+       } KeyMaterialInternal;
 }
diff --git a/librpc/idl/tpm20_rsakey_blob.idl b/librpc/idl/tpm20_rsakey_blob.idl
new file mode 100644
index 00000000000..5e0a1f081e1
--- /dev/null
+++ b/librpc/idl/tpm20_rsakey_blob.idl
@@ -0,0 +1,126 @@
+/*
+   Definitions for packing and unpacking TPM 2.0 Public key
+   structures, derived from:
+
+    https://dox.ipxe.org/Tpm20_8h_source.html#l00164
+    https://stackoverflow.com/questions/78958315/cannot-parse-tpm2-0-public-key
+
+   Note: This is a greatly simplified implementation, that:
+        - only handles TPM version 2.0 blobs
+        - only extracts the RSA public key
+        - ignores other fields
+       - and in the case of unions assumes that only the RSA option will
+         be present.
+*/
+
+#include "idl_types.h"
+
+[
+  pointer_default(unique)
+]
+interface tpm20_rsakey_blob
+{
+       const uint32 TPM20_MAGIC      = 0x4D504350; /* PCPM */
+
+       const uint32 PCP_TYPE_TPM_12  = 0x00000001;
+       const uint32 PCP_TYPE_TPM_20  = 0x00000002;
+
+       const uint16 TPM_ALG_RSA    = 0x0001;
+       const uint16 TPM_ALG_NULL   = 0x0010;
+       const uint16 TPM_ALG_SHA256 = 0x000B;
+       const uint16 TPM_ALG_RSASSA = 0x0014;
+
+
+       const uint16 TPM_RSA_EXPONENT_SIZE = sizeof(uint32_t);
+
+       /* Public structures. */
+       typedef struct {
+               /* Only supporting Public keys with SHA256 hashes */
+               [flag(NDR_BIG_ENDIAN), value(0x0014), range(0x0014, 0x0014)]
+                       uint16 scheme;
+               /*
+                * Strictly speaking this is a union but we're
+                * restricting the scheme to RSASSA, and the
+                * TPMS_SCHEME_RSA contains just the hash algorithm
+                */
+               [flag(NDR_BIG_ENDIAN), value(0x000B), range(0x000B, 0x000B)]
+                       uint16 hash_algorithm;
+       } TPMT_RSA_SCHEME;
+
+       typedef [public] struct {
+               /* Only catering for TPM_ALG_NONE */
+               [flag(NDR_BIG_ENDIAN), value(0x0010), range(0x0010, 0x0010)]
+                       uint16 symmetric_algorithm;
+               TPMT_RSA_SCHEME        scheme;
+               [flag(NDR_BIG_ENDIAN)] uint16   keyBits;
+               /*
+                * Defined in the spec as a big endian uint32, but defined
+                * here as a byte array for convenience
+                */
+               uint8 exponent[TPM_RSA_EXPONENT_SIZE];
+        } TPMS_RSA_PARMS;
+
+
+       typedef [public] struct {
+               [flag(NDR_BIG_ENDIAN)] uint16 size;
+               uint8 buffer[size];
+       } TPM2B_PUBLIC_KEY_RSA;
+
+       typedef [public] struct {
+               [flag(NDR_BIG_ENDIAN)] uint16    size;
+               uint8     buffer[size];
+       } TPM2B_DIGEST;
+
+       typedef [public] struct {
+               [flag(NDR_BIG_ENDIAN)] uint16 size;
+               /* definitions folded in from TPMT_PUBLIC */
+
+               /* Only supporting RSA Public keys with SHA256 hashes */
+               [flag(NDR_BIG_ENDIAN), value(0x0001), range(0x0001, 0x0001)]
+                       uint16               type;
+               [flag(NDR_BIG_ENDIAN), value(0x000B), range(0x000B, 0x000B)]
+                       uint16               hash_algorithm;
+               uint32               attributes;
+               TPM2B_DIGEST         auth_policy;
+               /*
+                * strictly speaking the next two elements are unions
+                * but we're only processing RSA entries, by restricting
+                * the values of type.
+                */
+               TPMS_RSA_PARMS       rsa_detail;
+               TPM2B_PUBLIC_KEY_RSA rsa;
+       } TPM2B_PUBLIC;
+
+       /*
+        * As far as I can tell the TPM20_KEY_BLOB is little endian,
+        * BUT the TPM2B_PUBLIC is big endian
+        */
+       typedef [public] struct {
+               [value(0x4D504350), range(0x4D504350, 0x4D504350)]
+                       uint32 magic; /* PCPM */
+               [value(46)] uint32 header_length;
+               /* Only supporting version 2.0 blobs */
+               [value(0x00000002), range(0x00000002, 0x00000002)]
+                       uint32 type;
+               uint32 flags;
+               uint32 public_length;
+               /*
+               * Ignore the rest of the lengths and the pcra_alg_id
+               * only getting the public key, for key trust authentication
+               */
+               uint32 private_length;
+               uint32 migration_public_length;
+               uint32 migration_private_length;
+               uint32 policy_digest_list_length;
+               uint32 pcr_binding_length;
+               uint32 pcr_digest_length;
+               uint32 encrypted_secret_length;
+               uint32 tpm12_hostage_blob_length;
+               uint16 pcr_alg_id;
+
+               /* Lets get the public key */
+               [flag(NDR_NOALIGN)] TPM2B_PUBLIC public_key;
+               /* just collect all the remaining bytes after the public key */
+               [flag(NDR_REMAINING)] DATA_BLOB remaining;
+       } TPM20_RSAKEY_BLOB;
+}
diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build
index 8a8f97d8592..188fa45d651 100644
--- a/librpc/idl/wscript_build
+++ b/librpc/idl/wscript_build
@@ -141,9 +141,11 @@ bld.SAMBA_PIDL_LIST('PIDL',
                     nbt.idl
                     ntlmssp.idl
                     preg.idl
+                    bcrypt_rsakey_blob.idl
                     security.idl
                     server_id.idl
                     smb_acl.idl
+                    tpm20_rsakey_blob.idl
                     xattr.idl
                     smb3posix.idl
                     ''',
diff --git a/librpc/ndr/ndr_keycredlink.c b/librpc/ndr/ndr_keycredlink.c
index 967202978b6..2222e3bf666 100644
--- a/librpc/ndr/ndr_keycredlink.c
+++ b/librpc/ndr/ndr_keycredlink.c
@@ -23,9 +23,16 @@
 */
 
 #include "lib/replace/replace.h"
+
 #include "librpc/gen_ndr/ndr_keycredlink.h"
 #include "gen_ndr/keycredlink.h"
+#include "lib/util/data_blob.h"
+#include "lib/util/debug.h"
 #include "libndr.h"
+#include "librpc/gen_ndr/ndr_bcrypt_rsakey_blob.h"
+#include "librpc/gen_ndr/ndr_tpm20_rsakey_blob.h"
+#include "util/asn1.h"
+#include "util/data_blob.h"
 #include <assert.h>
 
 /*
@@ -439,3 +446,555 @@ enum ndr_err_code ndr_pull_KEYCREDENTIALLINK_ENTRY(
        ndr->flags = _flags_save_STRUCT;
        return NDR_ERR_SUCCESS;
 }
+
+/* @brief Check that the AlgorithmIdentifier element is correct
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ *     algorithm       OBJECT IDENTIFIER,
+ *     parameters      ANY DEFINED BY algorithm OPTIONAL
+ *                     -- Should be NULL for RSA
+ * }
+ *
+ * @param[in]     ndr ndr pull context
+ * @param[in,out] asn ASN data context
+ *
+ * @return NDR_ERR_SUCCESS if the element is valid.
+ */
+static enum ndr_err_code check_algorithm_identifier(struct ndr_pull *ndr,
+                                                   struct asn1_data *asn)
+{
+       static const char *RSA_ENCRYPTION_OID = "1.2.840.113549.1.1.1";
+       uint8_t asn1_null[2];
+       if (!asn1_start_tag(asn, ASN1_SEQUENCE(0))) {
+               return ndr_pull_error(
+                       ndr,
+                       NDR_ERR_VALIDATE,
+                       "Invalid ASN1 tag, expecting SEQUENCE 0x30");
+       }
+       if (!asn1_check_OID(asn, RSA_ENCRYPTION_OID)) {
+               return ndr_pull_error(
+                       ndr,
+                       NDR_ERR_VALIDATE,
+                       "Invalid ASN1 algorithm OID, expecting %s",
+                       RSA_ENCRYPTION_OID);
+       }
+
+       /* For an RSA public key, parameters should be null 0x0500 */
+       if (!asn1_read(asn, asn1_null, 2)) {
+               return ndr_pull_error(
+                       ndr,
+                       NDR_ERR_VALIDATE,
+                       "Unexpected ASN1 element, expecting NULL 0x05");
+       }
+       if (!asn1_end_tag(asn)) { /* AlgorithmIdentifier */
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_UNREAD_BYTES,
+                                     "ASN1 element AlgorithmIdentifier");
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+/**
+ * @brief start processing a BIT STRING
+ *
+ * The caller will need to call asn1_end_tag
+ *
+ * @param[in]     ndr         ndr pull context
+ * @param[in,out] asn         ASN data context
+ * @param[out]    unused_bits the number of unused bits in the least
+ *                            significant byte (LSB) of the BIT String
+ *
+ * @return NDR_ERR_SUCCESS if successful
+ *         The contents of unused_bits are undefined on an error
+ */
+static enum ndr_err_code start_bit_string(struct ndr_pull *ndr,
+                                         struct asn1_data *asn,
+                                         uint8_t *unused_bits)
+{
+       if (!asn1_start_tag(asn, ASN1_BIT_STRING)) {
+               return ndr_pull_error(
+                       ndr,
+                       NDR_ERR_VALIDATE,
+                       "Invalid ASN1 tag, expecting BIT STRING 0x03");
+       }
+
+       /*
+        * The first byte of a BIT STRING contains the number of unused bits
+        * in the final byte.
+        */
+       if (!asn1_read_uint8(asn, unused_bits)) {
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_VALIDATE,
+                                     "Invalid ASN1 BIT STRING, unable to read "
+                                     "number of unused bits");
+       }
+       if (*unused_bits > 8) {
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_RANGE,
+                                     "Invalid ASN1 BIT STRING, "
+                                     "number of unused bits exceeds 9");
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+/**
+ * @brief Read a DER encoded INTEGER into a data_blob
+ *
+ * @param[in]     mem_ctx memory context to allocate the data_blob data on
+ * @param[in]     ndr     ndr pull context
+ * @param[in,out] asn     ASN data context
+ * @param[in]     name    the name of the INTEGER for diagnostic messages
+ * @param[out]    blob    the data blob to populate
+ *                        using mem_ctx for allocation
+ *
+ * @return NDR_ERR_SUCCESS if successful
+ *         The contents of blob are undefined on an error
+ */
+static enum ndr_err_code read_integer(TALLOC_CTX *mem_ctx,
+                                     struct ndr_pull *ndr,
+                                     struct asn1_data *asn,
+                                     const char *name,
+                                     DATA_BLOB *blob)
+{
+       static const int MAX_SIZE = 2 * 2048; /* 16384 bits */
+       uint8_t msb = 0;
+       int tag_size = 0;
+
+       if (!asn1_start_tag(asn, ASN1_INTEGER)) {
+               return ndr_pull_error(
+                       ndr,
+                       NDR_ERR_VALIDATE,
+                       "Invalid ASN1 tag, expecting INTEGER 0x02");
+       }
+       if (!asn1_peek_uint8(asn, &msb)) {
+               return ndr_pull_error(
+                       ndr,
+                       NDR_ERR_VALIDATE,
+                       "Invalid ASN1 tag, unable to inspect first byte of %s",
+                       name);
+       }
+       /* skip a leading 0 byte if present */
+       if (msb == 0) {
+               if (!asn1_read_uint8(asn, &msb)) {
+                       return ndr_pull_error(ndr,
+                                             NDR_ERR_VALIDATE,
+                                             "Invalid ASN1 tag, unable to "
+                                             "read first byte of %s",
+                                             name);
+               }
+       }
+
+       tag_size = asn1_tag_remaining(asn);
+       if (tag_size > MAX_SIZE) {
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_LENGTH,
+                                     "INTEGER %s size of %d "
+                                     "bytes is too large",
+                                     name,
+                                     tag_size);
+       }
+       if (tag_size <= 0) {
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_LENGTH,
+                                     "INTEGER %s size of %d "
+                                     "bytes is too small",
+                                     name,
+                                     tag_size);
+       }
+       *blob = data_blob_talloc(mem_ctx, NULL, tag_size);
+       if (blob->data == NULL) {
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_ALLOC,
+                                     "Unable to allocate DATA_BLOB for %s",
+                                     name);
+       }
+
+       if (!asn1_read(asn, blob->data, tag_size)) {
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_VALIDATE,
+                                     "Unable to read %s",
+                                     name);
+       }
+       if (!asn1_end_tag(asn)) {
+               return ndr_pull_error(ndr,
+                                     NDR_ERR_UNREAD_BYTES,
+                                     "ASN1 INTEGER element %s",
+                                     name);
+       }
+       return NDR_ERR_SUCCESS;
+}
+


-- 
Samba Shared Repository

Reply via email to