⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn1.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* read from a ASN1 buffer, advancing the buffer pointer */bool asn1_read(struct asn1_data *data, void *p, int len){	if (!asn1_peek(data, p, len)) {		data->has_error = true;		return false;	}	data->ofs += len;	return true;}/* read a uint8_t from a ASN1 buffer */bool asn1_read_uint8(struct asn1_data *data, uint8_t *v){	return asn1_read(data, v, 1);}bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v){	return asn1_peek(data, v, 1);}bool asn1_peek_tag(struct asn1_data *data, uint8_t tag){	uint8_t b;	if (asn1_tag_remaining(data) <= 0) {		return false;	}	if (!asn1_peek_uint8(data, &b))		return false;	return (b == tag);}/* start reading a nested asn1 structure */bool asn1_start_tag(struct asn1_data *data, uint8_t tag){	uint8_t b;	struct nesting *nesting;		if (!asn1_read_uint8(data, &b))		return false;	if (b != tag) {		data->has_error = true;		return false;	}	nesting = talloc(data, struct nesting);	if (!nesting) {		data->has_error = true;		return false;	}	if (!asn1_read_uint8(data, &b)) {		return false;	}	if (b & 0x80) {		int n = b & 0x7f;		if (!asn1_read_uint8(data, &b))			return false;		nesting->taglen = b;		while (n > 1) {			if (!asn1_read_uint8(data, &b)) 				return false;			nesting->taglen = (nesting->taglen << 8) | b;			n--;		}	} else {		nesting->taglen = b;	}	nesting->start = data->ofs;	nesting->next = data->nesting;	data->nesting = nesting;	if (asn1_tag_remaining(data) == -1) {		return false;	}	return !data->has_error;}/* stop reading a tag */bool asn1_end_tag(struct asn1_data *data){	struct nesting *nesting;	/* make sure we read it all */	if (asn1_tag_remaining(data) != 0) {		data->has_error = true;		return false;	}	nesting = data->nesting;	if (!nesting) {		data->has_error = true;		return false;	}	data->nesting = nesting->next;	talloc_free(nesting);	return true;}/* work out how many bytes are left in this nested tag */int asn1_tag_remaining(struct asn1_data *data){	int remaining;	if (data->has_error) {		return -1;	}	if (!data->nesting) {		data->has_error = true;		return -1;	}	remaining = data->nesting->taglen - (data->ofs - data->nesting->start);	if (remaining > (data->length - data->ofs)) {		data->has_error = true;		return -1;	}	return remaining;}/* read an object ID from a data blob */bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID){	int i;	uint8_t *b;	uint_t v;	char *tmp_oid = NULL;	if (blob.length < 2) return false;	b = blob.data;	tmp_oid = talloc_asprintf(mem_ctx, "%u",  b[0]/40);	if (!tmp_oid) goto nomem;	tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  b[0]%40);	if (!tmp_oid) goto nomem;	for(i = 1, v = 0; i < blob.length; i++) {		v = (v<<7) | (b[i]&0x7f);		if ( ! (b[i] & 0x80)) {			tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  v);			v = 0;		}		if (!tmp_oid) goto nomem;	}	if (v != 0) {		talloc_free(tmp_oid);		return false;	}	*OID = tmp_oid;	return true;nomem:		return false;}/* read an object ID from a ASN1 buffer */bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID){	DATA_BLOB blob;	int len;	if (!asn1_start_tag(data, ASN1_OID)) return false;	len = asn1_tag_remaining(data);	if (len < 0) {		data->has_error = true;		return false;	}	blob = data_blob(NULL, len);	if (!blob.data) {		data->has_error = true;		return false;	}	asn1_read(data, blob.data, len);	asn1_end_tag(data);	if (data->has_error) {		data_blob_free(&blob);		return false;	}	if (!ber_read_OID_String(mem_ctx, blob, OID)) {		data->has_error = true;		data_blob_free(&blob);		return false;	}	data_blob_free(&blob);	return true;}/* check that the next object ID is correct */bool asn1_check_OID(struct asn1_data *data, const char *OID){	const char *id;	if (!asn1_read_OID(data, data, &id)) return false;	if (strcmp(id, OID) != 0) {		talloc_free(discard_const(id));		data->has_error = true;		return false;	}	talloc_free(discard_const(id));	return true;}/* read a LDAPString from a ASN1 buffer */bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s){	int len;	len = asn1_tag_remaining(data);	if (len < 0) {		data->has_error = true;		return false;	}	*s = talloc_array(mem_ctx, char, len+1);	if (! *s) {		data->has_error = true;		return false;	}	asn1_read(data, *s, len);	(*s)[len] = 0;	return !data->has_error;}/* read a GeneralString from a ASN1 buffer */bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s){	if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false;	if (!asn1_read_LDAPString(data, mem_ctx, s)) return false;	return asn1_end_tag(data);}/* read a octet string blob */bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob){	int len;	ZERO_STRUCTP(blob);	if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false;	len = asn1_tag_remaining(data);	if (len < 0) {		data->has_error = true;		return false;	}	*blob = data_blob_talloc(mem_ctx, NULL, len+1);	if (!blob->data) {		data->has_error = true;		return false;	}	asn1_read(data, blob->data, len);	asn1_end_tag(data);	blob->length--;	blob->data[len] = 0;		if (data->has_error) {		data_blob_free(blob);		*blob = data_blob(NULL, 0);		return false;	}	return true;}bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob){	int len;	ZERO_STRUCTP(blob);	if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;	len = asn1_tag_remaining(data);	if (len < 0) {		data->has_error = true;		return false;	}	*blob = data_blob(NULL, len);	if ((len != 0) && (!blob->data)) {		data->has_error = true;		return false;	}	asn1_read(data, blob->data, len);	asn1_end_tag(data);	return !data->has_error;}/* read an integer without tag*/bool asn1_read_implicit_Integer(struct asn1_data *data, int *i){	uint8_t b;	*i = 0;	while (!data->has_error && asn1_tag_remaining(data)>0) {		if (!asn1_read_uint8(data, &b)) return false;		*i = (*i << 8) + b;	}	return !data->has_error;		}/* read an integer */bool asn1_read_Integer(struct asn1_data *data, int *i){	*i = 0;	if (!asn1_start_tag(data, ASN1_INTEGER)) return false;	if (!asn1_read_implicit_Integer(data, i)) return false;	return asn1_end_tag(data);	}/* read an integer */bool asn1_read_enumerated(struct asn1_data *data, int *v){	*v = 0;		if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;	while (!data->has_error && asn1_tag_remaining(data)>0) {		uint8_t b;		asn1_read_uint8(data, &b);		*v = (*v << 8) + b;	}	return asn1_end_tag(data);	}/* check a enumerated value is correct */bool asn1_check_enumerated(struct asn1_data *data, int v){	uint8_t b;	if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;	asn1_read_uint8(data, &b);	asn1_end_tag(data);	if (v != b)		data->has_error = false;	return !data->has_error;}/* write an enumerated value to the stream */bool asn1_write_enumerated(struct asn1_data *data, uint8_t v){	if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false;	asn1_write_uint8(data, v);	asn1_pop_tag(data);	return !data->has_error;}/*  check if a ASN.1 blob is a full tag*/NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size){	struct asn1_data *asn1 = asn1_init(NULL);	int size;	NT_STATUS_HAVE_NO_MEMORY(asn1);	asn1->data = blob.data;	asn1->length = blob.length;	asn1_start_tag(asn1, tag);	if (asn1->has_error) {		talloc_free(asn1);		return STATUS_MORE_ENTRIES;	}	size = asn1_tag_remaining(asn1) + asn1->ofs;	talloc_free(asn1);	if (size > blob.length) {		return STATUS_MORE_ENTRIES;	}			*packet_size = size;	return NT_STATUS_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -