70 行
2.6 KiB
C
70 行
2.6 KiB
C
#ifndef PAZE_ASN1_H
|
|
#define PAZE_ASN1_H
|
|
#include "paze/paze_types.h"
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* 最小 ASN.1/DER 子集,够 RSA/PKCS#1、X.509、EC 公钥解析用 */
|
|
|
|
/* DER 标签 */
|
|
#define ASN1_BOOLEAN 0x01
|
|
#define ASN1_INTEGER 0x02
|
|
#define ASN1_BITSTRING 0x03
|
|
#define ASN1_OCTETSTRING 0x04
|
|
#define ASN1_NULL 0x05
|
|
#define ASN1_OID 0x06
|
|
#define ASN1_UTF8 0x0C
|
|
#define ASN1_SEQUENCE 0x30
|
|
#define ASN1_SET 0x31
|
|
#define ASN1_CTX0 0xA0
|
|
#define ASN1_CTX1 0xA1
|
|
#define ASN1_CTX3 0xA3
|
|
|
|
typedef struct {
|
|
const uint8_t *p;
|
|
const uint8_t *end;
|
|
} paze_asn1_reader_t;
|
|
|
|
void paze_asn1_r_init(paze_asn1_reader_t *r, const uint8_t *der, size_t len);
|
|
/* 读取下一个 TLV;tag 写入 *tag,body 起始指针写入 *body,len 写入 *blen。
|
|
* 返回 PAZE_OK 或 PAZE_ERR_FORMAT。读取后 r->p 推进到 TLV 之后。 */
|
|
paze_status_t paze_asn1_read_tl(paze_asn1_reader_t *r, uint8_t *tag,
|
|
const uint8_t **body, size_t *blen);
|
|
/* 进入 SEQUENCE 子阅读器 */
|
|
paze_status_t paze_asn1_enter_seq(paze_asn1_reader_t *r, paze_asn1_reader_t *child);
|
|
int paze_asn1_at_end(const paze_asn1_reader_t *r); /* 1 表示已到末尾 */
|
|
|
|
/* 读 INTEGER 为大端字节(去除前导零),写入 out(*outlen 给出容量,实际写回)。
|
|
负数不支持(密码学场景用不到)。*/
|
|
paze_status_t paze_asn1_read_integer(paze_asn1_reader_t *r,
|
|
uint8_t *out, size_t *outlen);
|
|
|
|
/* ---- DER 编码器(写入增长缓冲区) ---- */
|
|
typedef struct {
|
|
uint8_t *buf;
|
|
size_t cap;
|
|
size_t len;
|
|
int own; /* 1=自己 malloc,出错需 paze_asn1_w_free */
|
|
} paze_asn1_writer_t;
|
|
|
|
void paze_asn1_w_init(paze_asn1_writer_t *w, uint8_t *buf, size_t cap);
|
|
paze_status_t paze_asn1_w_reserve(paze_asn1_writer_t *w, size_t extra);
|
|
void paze_asn1_w_free(paze_asn1_writer_t *w);
|
|
|
|
paze_status_t paze_asn1_w_byte(paze_asn1_writer_t *w, uint8_t b);
|
|
paze_status_t paze_asn1_w_data(paze_asn1_writer_t *w, const uint8_t *d, size_t n);
|
|
paze_status_t paze_asn1_w_tag_len(paze_asn1_writer_t *w, uint8_t tag, size_t len);
|
|
paze_status_t paze_asn1_w_integer(paze_asn1_writer_t *w, const uint8_t *be, size_t n);
|
|
paze_status_t paze_asn1_w_null(paze_asn1_writer_t *w);
|
|
paze_status_t paze_asn1_w_oid(paze_asn1_writer_t *w, const uint8_t *oid_der, size_t n);
|
|
|
|
/* 把已写好的 body 内容包成 TLV。更高级用法见实现 */
|
|
paze_status_t paze_asn1_w_wrap(paze_asn1_writer_t *w, uint8_t tag,
|
|
const uint8_t *body, size_t n);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|