x509.h
#ifndef _X509_H_
#define _X509_H_ 1
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct x509_t X509_T;
X509_T* x509_create (uint8_t *derData, uint32_t derSize);
void x509_destroy (X509_T *x509);
uint8_t* x509_getPublicKey (X509_T *x509, uint32_t *keyLen, uint32_t *exponent);
#ifdef __cplusplus
}
#endif
#endif
x509.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "x509.h"
#define DER_TAG_Integer 0x02
#define DER_TAG_BitString 0x03
#define DER_TAG_ObjectIdentifier 0x06
#define DER_TAG_UtcTime 0x17
#define DER_TAG_Sequence 0x30
#define DER_TAG_Version 0xa0
/*
// 签名算法描述符
AlgorithmIdentifier::=SEQUENCE{
algorithm OBJECT IDENTIFIER, // 算法OID。
parameters ANY DEFINED BY algorithm OPTIONAL // 可选的参数,由算法决定。
}
// 算法OID:
1.2.840.113549.1.1.4 MD5 + RSA
1.2.840.113549.1.1.5 SHA1 + RSA
// 属性的类型和值
AttributeTypeAndValue::=SEQUENCE{
type AttributeType, // 属性类型。AttributeType::=OBJECT IDENTIFIER
value AttributeValue // 属性的值。AttributeValue::=ANY DEFINED BY AttributeType
}
// 相对可分辨名称
RelativeDistinguishedName::=SET OF AttributeTypeAndValue
// RDN序列
RDNSequence::=SEQUENCE OF RelativeDistinguishedName
// 名字结构
Name::=CHOICE{
RDNSequence
}
// 时间结构
Time::=CHOICE{
utcTime UTCTime,
generalTime GeneralizedTime
}
// 有效期
Validity::=SEQUENCE{
notBefore Time, // 时间段起点时间
notAfter Time // 时间段终点时间
}
// 主体公钥信息
SubjectPublicKeyInfo::=SEQUENCE{
algorithm AlgorithmIdentifier, // 签名算法描述符。
subjectPublicKey BIT STRING // 公钥数据。
}
// 证书内容。
TBSCertificate::=SEQUENCE{
version [0] EXPLICIT Version DEFAULT v1, // 版本号。 Version::=INTEGER {v1(0),v2(1),v3(2)}
serialNumber CertificateSerialNumber, // 序列号。 CertificateSerialNumber::=INTEGER
signature AlgorithmIdentifier, // 签名算法描述符。
issuer Name, // 证书签发者。
validity Validity, // 有效期。
subject Name, // 证书持有者。
subjectPublicKeyInfo SubjectPublicKeyInfo, // 主体公钥信息。
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, // 签发者唯一标识符,仅V2和V3有这个字段。 UniqueIdentifier::=BIT STRING
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, // 主体唯一标识符,仅V2和V3有这个字段。 UniqueIdentifier::=BIT STRING
extensions [3] EXPLICIT Extensions OPTIONAL // 扩展数据,仅V3版本有此字段。
}
// X.509 证书整体格式
Certificate::=SEQUENCE{
tbsCertificate TBSCertificate, // 证书内容。
signatureAlgorithm AlgorithmIdentifier, // 签名算法描述符。
signatureValue BIT STRING // 签名结果值,位流。
}
*/
struct x509_t {
uint8_t *serialNumber; // 序列号
uint8_t *algorithm; // 签名算法描述符
uint8_t *parameters; // 签名算法所需参数
uint8_t *notBefore; // 有效期起始时间
uint8_t *notAfter; // 有效期终止时间
uint8_t *signature; // 签名结果值数据
uint8_t *keyModulus; // RSA公钥模数
uint16_t version; // X.509 版本号
uint16_t serialNumberSize; // 序列号字节数
uint16_t algorithmSize; // 签名算法描述符字节数
uint16_t parametersSize; // 签名算法所需参数字节数
uint16_t notBeforeSize; // 有效期起始时间字节数
uint16_t notAfterSize; // 有效期终止时间字节数
uint16_t signatureSize; // 签名结果值数据字节数
uint16_t keyModulusSize; // RSA公钥模数字节数
uint32_t keyExponent; // RSA公钥指数
uint8_t buffer[0]; //
};
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
static inline uint16_t readU16BE(uint8_t *buffer){
uint16_t value = 0;
value = (value << 8) | buffer[0];
value = (value << 8) | buffer[1];
return value;
}
static inline uint32_t readU24BE(uint8_t *buffer){
uint32_t value = 0;
value = (value << 8) | buffer[0];
value = (value << 8) | buffer[1];
value = (value << 8) | buffer[2];
return value;
}
static inline uint32_t readU32BE(uint8_t *buffer){
uint32_t value = 0;
value = (value << 8) | buffer[0];
value = (value << 8) | buffer[1];
value = (value << 8) | buffer[2];
value = (value << 8) | buffer[3];
return value;
}
static uint8_t getTLV(uint8_t *tag, uint32_t *length, uint8_t *data){
*tag = data[0];
if(data[1] < 128){
*length = data[1];
return 2;
}else{
uint8_t num = data[1] & 0x7f;
switch(num){
case 1:
*length = data[2];
return 3;
case 2:
*length = readU16BE(data+2);
return 4;
case 3:
*length = readU24BE(data+2);
return 5;
case 4:
*length = readU32BE(data+2);
return 6;
}
}
*tag = 0;
*length = 0;
return 0;
}
// 读取算法描述符及其所需参数
static void readSignatureAlgorithm(X509_T *x509, uint8_t *data, uint32_t size){
// 算法描述符 ObjectIdentifier
uint8_t tag;
uint32_t length;
uint8_t head = getTLV(&tag, &length, data);
if((head) && (tag == DER_TAG_ObjectIdentifier)){
x509->algorithm = data + head;
x509->algorithmSize = length;
}else{
return;
}
}
// 读取 X.509 版本号
static void readVersion(X509_T *x509, uint8_t *data, uint32_t size){
uint8_t tag;
uint32_t length;
uint8_t head = getTLV(&tag, &length, data);
if((head) && (tag == DER_TAG_Integer)){
x509->version = data[head];
}
}
// 读取有效期
static void readValidity(X509_T *x509, uint8_t *data, uint32_t size){
uint8_t head;
uint8_t tag;
uint32_t length;
uint32_t offset = 0;
// 读取 notBefore
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_UtcTime)){
x509->notBefore = data + offset + head;
x509->notBeforeSize = length;
offset += length + head;
}else{
return;
}
// 读取 notAfter
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_UtcTime)){
x509->notAfter = data + offset + head;
x509->notAfterSize = length;
offset += length + head;
}else{
return;
}
}
// 读取公钥信息
static void readSubjectPublicKeyInfo(X509_T *x509, uint8_t *data, uint32_t size){
uint8_t head;
uint8_t tag;
uint32_t length;
uint32_t offset = 0;
// 读取算法描述符。 略过。
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
offset += length + head;
}else{
return;
}
// 解开位流包。位流包解开后还有一层序列包。
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_BitString)){
if(data[offset+head]){
data = data + offset + head;
size = length;
}else{
data = data + offset + head + 1;
size = length - 1;
}
offset = 0;
}else{
return;
}
// 解开序列包。序列包解开后就是公钥模数和指数。
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
data = data + offset + head;
size = length;
offset = 0;
}else{
return;
}
// 读取 RSA公钥模数
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Integer)){
if((data[offset+head]) || (length%16 == 0)){
x509->keyModulus = data + offset + head;
x509->keyModulusSize = length;
}else{
x509->keyModulus = data + offset + head + 1;
x509->keyModulusSize = length - 1;
}
offset += length + head;
}else{
return;
}
// 读取 RSA公钥指数
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Integer)){
if(length == 1){
x509->keyExponent = data[offset+head];
}else if(length == 2){
x509->keyExponent = readU16BE(data+offset+head);
}else if(length == 3){
x509->keyExponent = readU24BE(data+offset+head);
}else if(length == 4){
x509->keyExponent = readU32BE(data+offset+head);
}else{
return;
}
}else{
return;
}
}
// 读取证书主体内容
static void readtbsCertificate(X509_T *x509, uint8_t *data, uint32_t size){
uint8_t head;
uint8_t tag;
uint32_t length;
uint32_t offset = 0;
// 读取 X.509 版本号
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Version)){
readVersion(x509, data+offset+head, length);
offset += length + head;
}else{
return;
}
// 读取序列号
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Integer)){
x509->serialNumber = data + offset + head;
x509->serialNumberSize = length;
offset += length + head;
}else{
return;
}
// 读取签名算法描述符。 略过,因为后面还有。
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
offset += length + head;
}else{
return;
}
// 读取证书发行者。 略过。
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
offset += length + head;
}else{
return;
}
// 读取有效期
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
readValidity(x509, data+offset+head, length);
offset += length + head;
}else{
return;
}
// 读取证书持有者。 略过。
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
offset += length + head;
}else{
return;
}
// 读取公钥信息
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
readSubjectPublicKeyInfo(x509, data+offset+head, length);
offset += length + head;
}else{
return;
}
}
// 读取整个证书
static void readCertificate(X509_T *x509, uint8_t *data, uint32_t size){
uint8_t head;
uint8_t tag;
uint32_t length;
uint32_t offset = 0;
// 证书内容 TBSCertificate
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
readtbsCertificate(x509, data+offset+head, length);
offset += length + head;
}else{
return;
}
// 签名算法描述符 AlgorithmIdentifier
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_Sequence)){
readSignatureAlgorithm(x509, data+offset+head, length);
offset += length + head;
}else{
return;
}
// 签名结果值 BitString
head = getTLV(&tag, &length, data+offset);
if((head) && (tag == DER_TAG_BitString)){
if((data[offset+head]) || (length%16 == 0)){
x509->signature = data + offset + head;
x509->signatureSize = length;
}else{
x509->signature = data + offset + head + 1;
x509->signatureSize = length - 1;
}
}else{
return;
}
}
/*
static void X509_dump(X509_T *x509){
printf("x509:\n");
printf(" version: %u\n", x509->version);
if((x509->serialNumber) && (x509->serialNumberSize)){
printf(" serialNumberSize: %u\n", x509->serialNumberSize);
printf(" serialNumberValue:\n");
common_hex(" ", "\e[32m", x509->serialNumber, x509->serialNumberSize);
}
if((x509->algorithm) && (x509->algorithmSize)){
printf(" algorithmSize: %u\n", x509->algorithmSize);
printf(" algorithmValue:\n");
common_hex(" ", "\e[32m", x509->algorithm, x509->algorithmSize);
}
if((x509->notBefore) && (x509->notBeforeSize)){
printf(" notBeforeSize: %u\n", x509->notBeforeSize);
printf(" notBeforeValue:\n");
common_hex(" ", "\e[32m", x509->notBefore, x509->notBeforeSize);
}
if((x509->notAfter) && (x509->notAfterSize)){
printf(" notAfterSize: %u\n", x509->notAfterSize);
printf(" notAfterValue:\n");
common_hex(" ", "\e[32m", x509->notAfter, x509->notAfterSize);
}
if((x509->signature) && (x509->signatureSize)){
printf(" signatureSize: %u\n", x509->signatureSize);
printf(" signatureValue:\n");
common_hex(" ", "\e[32m", x509->signature, x509->signatureSize);
}
if((x509->keyModulus) && (x509->keyModulusSize)){
printf(" keyModulusSize: %u\n", x509->keyModulusSize);
printf(" keyModulusValue:\n");
common_hex(" ", "\e[34m", x509->keyModulus, x509->keyModulusSize);
}
printf(" keyExponent: %u\n\n", x509->keyExponent);
}
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// 通过DER格式的X.509证书创建X509结构体。
X509_T* x509_create(uint8_t *derData, uint32_t derSize){
X509_T *x509 = malloc(sizeof(X509_T) + derSize + 8);
if(x509 == NULL) return NULL;
memset(x509, 0, sizeof(X509_T));
memcpy(x509->buffer, derData, derSize);
uint8_t tag;
uint32_t length;
uint8_t head = getTLV(&tag, &length, x509->buffer);
if((head) && (tag == DER_TAG_Sequence) && (length+head <= derSize)){
readCertificate(x509, x509->buffer+head, length);
// X509_dump(x509);
return x509;
}else{
free(x509);
return NULL;
}
}
// 销毁X509结构
void x509_destroy(X509_T *x509){
free(x509);
}
// 从X509结构获取RSA公钥
uint8_t* x509_getPublicKey(X509_T *x509, uint32_t *keyLen, uint32_t *exponent){
*keyLen = x509->keyModulusSize;
*exponent = x509->keyExponent;
return x509->keyModulus;
}
网友评论