summaryrefslogtreecommitdiff
path: root/lib/util/asn1.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/util/asn1.c')
-rw-r--r--lib/util/asn1.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/lib/util/asn1.c b/lib/util/asn1.c
index a2665ed539..70c2c57450 100644
--- a/lib/util/asn1.c
+++ b/lib/util/asn1.c
@@ -205,6 +205,15 @@ bool asn1_write_Integer(struct asn1_data *data, int i)
return asn1_pop_tag(data);
}
+/* write a BIT STRING */
+bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding)
+{
+ if (!asn1_push_tag(data, ASN1_BIT_STRING)) return false;
+ if (!asn1_write_uint8(data, padding)) return false;
+ if (!asn1_write(data, p, length)) return false;
+ return asn1_pop_tag(data);
+}
+
bool ber_write_OID_String(DATA_BLOB *blob, const char *OID)
{
uint_t v, v2;
@@ -262,6 +271,7 @@ bool asn1_write_OID(struct asn1_data *data, const char *OID)
}
if (!asn1_write(data, blob.data, blob.length)) {
+ data_blob_free(&blob);
data->has_error = true;
return false;
}
@@ -332,6 +342,29 @@ bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v)
return !data->has_error;
}
+/* write a BOOLEAN in a simple context */
+bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context)
+{
+ asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context));
+ asn1_write_uint8(data, v ? 0xFF : 0);
+ asn1_pop_tag(data);
+ return !data->has_error;
+}
+
+bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context)
+{
+ uint8_t tmp = 0;
+ asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context));
+ asn1_read_uint8(data, &tmp);
+ if (tmp == 0xFF) {
+ *v = true;
+ } else {
+ *v = false;
+ }
+ asn1_end_tag(data);
+ return !data->has_error;
+}
+
/* check a BOOLEAN */
bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
{
@@ -653,7 +686,7 @@ bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLO
if (data->has_error) {
data_blob_free(blob);
- *blob = data_blob(NULL, 0);
+ *blob = data_blob_null;
return false;
}
return true;
@@ -703,6 +736,39 @@ bool asn1_read_Integer(struct asn1_data *data, int *i)
return asn1_end_tag(data);
}
+/* read a BIT STRING */
+bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding)
+{
+ int len;
+ ZERO_STRUCTP(blob);
+ if (!asn1_start_tag(data, ASN1_BIT_STRING)) return false;
+ len = asn1_tag_remaining(data);
+ if (len < 0) {
+ data->has_error = true;
+ return false;
+ }
+ if (!asn1_read_uint8(data, padding)) return false;
+
+ *blob = data_blob_talloc(mem_ctx, NULL, len);
+ if (!blob->data) {
+ data->has_error = true;
+ return false;
+ }
+ if (asn1_read(data, blob->data, len - 1)) {
+ blob->length--;
+ blob->data[len] = 0;
+ asn1_end_tag(data);
+ }
+
+ if (data->has_error) {
+ data_blob_free(blob);
+ *blob = data_blob_null;
+ *padding = 0;
+ return false;
+ }
+ return true;
+}
+
/* read an integer */
bool asn1_read_enumerated(struct asn1_data *data, int *v)
{
@@ -741,6 +807,32 @@ bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
}
/*
+ Get us the data just written without copying
+*/
+bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
+{
+ if (asn1->has_error) {
+ return false;
+ }
+ if (asn1->nesting != NULL) {
+ return false;
+ }
+ blob->data = asn1->data;
+ blob->length = asn1->length;
+ return true;
+}
+
+/*
+ Fill in an asn1 struct without making a copy
+*/
+void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
+{
+ ZERO_STRUCTP(data);
+ data->data = buf;
+ data->length = len;
+}
+
+/*
check if a ASN.1 blob is a full tag
*/
NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)