ASN.1 Encode an Object Identifier (OID) with OpenSSL
OID(Object Identifier) denotes an object.
Examples:
------------------------------------------------------------------
OID object
------------------------------------------------------------------
1.3.14.3.2.26 SHA-1
2.16.840.1.101.3.4.2.1 SHA-256
1.2.840.113549.1.7.2 PKCS-7 signedData
------------------------------------------------------------------
In OpenSSL no functions are directly provided to compute the OID ASN.1 encode. At lease two methods can be taken into account.
1. Create a temporary object by invoking function OBJ_create(), then encode it by invoking function i2d_ASN1_OBJECT().
Implementation (Not recommended)
/**************************************************
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: Oct 11th, 2014
* Description: implement the OID ASN.1 encode function
**************************************************/ #include <stdio.h>
#include <openssl/objects.h>
#include <openssl/asn1.h> int Asn1EncodeOid(char *oid,
unsigned char *encode,
int *encode_len)
{
int new_nid, byte_len;
ASN1_OBJECT *obj;
unsigned char *tmp_pointer; new_nid = OBJ_create(oid, "oid example", "Object Identifier Example");
obj = OBJ_nid2obj(new_nid); if (!encode)
{
byte_len = i2d_ASN1_OBJECT(obj, NULL);
if (byte_len <= 0)
{
#ifdef _DEBUG
printf("get ASN.1 encode byte length failed at %s, line %d!\n", __FILE__, __LINE__);
#endif
OBJ_cleanup();
return (-1);
}
else
{
*encode_len = byte_len;
OBJ_cleanup();
return 0;
}
}
else
{
tmp_pointer = encode;
byte_len = i2d_ASN1_OBJECT(obj, &tmp_pointer);
if (byte_len <= 0)
{
#ifdef _DEBUG
printf("ASN.1 encode OID failed at %s, line %d!\n", __FILE__, __LINE__);
#endif
OBJ_cleanup();
return (-1);
}
else
{
*encode_len = byte_len;
OBJ_cleanup();
return 0;
}
}
}
This is not a good implementation. OBJ_cleanup() will free all dynamically created object, so this function must be used carefully. Especially when multiple threads are running, the fact that one thread invokes OBJ_cleanup() may run the risk of cleaning object
created by other threads. The consequence is unpredictable.
2. Compute OID payload part ASN.1 encode by invoking function a2d_ASN1_OBJECT() firstly, compute the OID encode by invoking function i2d_ASN1_OBJECT() next.
A complete Implementation (recommended)
Header file:
/**************************************************
* File name: oid_encode.h
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: Oct 11th, 2014
* Description: declare the OID ASN.1 encode function
**************************************************/ #ifndef HEADER_OID_ASN1_ENCODE_H
#define HEADER_OID_ASN1_ENCODE_H #ifdef __cplusplus
extern "C" {
#endif /**************************************************
* Name: Asn1EncodeOid
* Function: compute ASN.1 encode for a specific OID
* Parameters:
oid [in] OID string terminated with '\0'
encode [in] buffer used to store OID ASN.1 encode
encode_len [out] byte length of OID ASN.1 encode
* Return value:
succeed -- 0
fail -- -1
* Notes:
1. If the NULL pointer is assigned to parameter 'encode',
this function does not perform ASN.1 encode. The OID ASN.1
encode length is assigned to parameter 'encode_len' and
the function returns.
2. If the value assigned to parameter 'encode' is not NULL,
the OID ASN.1 encode is written into the buffer pointed by
parameter 'encode', and encode length is assigned to
parameter 'encode_len'. In this case the buffer length is
NOT checked before the encode is written into the buffer.
MAKE SURE that the buffer length is big enough to accomodate
the ASN.1 encode!
**************************************************/
int Asn1EncodeOid(char *oid, unsigned char *encode, int *encode_len); #ifdef __cplusplus
}
#endif #endif /* end of HEADER_OID_ASN1_ENCODE_H */
Function implementation file:
/**************************************************
* File name: oid_encode.c
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: Oct 11th, 2014
* Description: implement the OID ASN.1 encode function
**************************************************/ #include <stdio.h>
#include <openssl/objects.h>
#include <openssl/asn1.h> int Asn1EncodeOid(char *oid,
unsigned char *encode,
int *encode_len)
{
int payload_len, total_len;
ASN1_OBJECT obj;
unsigned char *tmp_pointer, *payload_encode; // get payload ASN.1 encode
payload_len = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
if (payload_len <= 0)
{
#ifdef _DEBUG
printf("get ASN.1 encode byte length failed at %s, line %d!\n", __FILE__, __LINE__);
#endif
return (-1);
}
if ( !(payload_encode=(unsigned char *)malloc(payload_len)) )
{
#ifdef _DEBUG
printf("invoke malloc() function failed at %s, line %d!\n", __FILE__, __LINE__);
#endif
return (-1);
}
payload_len = a2d_ASN1_OBJECT(payload_encode, payload_len, oid, -1);
if (payload_len <= 0)
{
#ifdef _DEBUG
printf("ASN.1 encode payload failed at %s, line %d!\n", __FILE__, __LINE__);
#endif
free(payload_encode);
return (-1);
} // get the whole OID ASN.1 encode
obj.data = payload_encode;
obj.length = payload_len;
if (!encode)
{
total_len = i2d_ASN1_OBJECT(&obj, NULL);
if (total_len <= 0)
{
#ifdef _DEBUG
printf("get ASN.1 encode byte length failed at %s, line %d!\n", __FILE__, __LINE__);
#endif
free(payload_encode);
return (-1);
}
else
{
*encode_len = total_len;
free(payload_encode);
return 0;
}
}
else
{
tmp_pointer = encode;
total_len = i2d_ASN1_OBJECT(&obj, &tmp_pointer);
if (total_len <= 0)
{
#ifdef _DEBUG
printf("ASN.1 encode OID failed at %s, line %d!\n", __FILE__, __LINE__);
#endif
free(payload_encode);
return (-1);
}
else
{
*encode_len = total_len;
free(payload_encode);
return 0;
}
}
}
A demo program file:
/**************************************************
* File name: test.c
* Author: HAN Wei
* Author's blog: http://blog.csdn.net/henter/
* Date: Oct 11th, 2014
* Description: this program demonstrates how to invoke
the OID ASN.1 encode function
**************************************************/ #include "oid_encode.h"
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char oid[128]="2.16.840.1.101.3.4.2.1"; /* SHA-256 OID*/
unsigned char *buffer;
int buffer_len, i; if ( Asn1EncodeOid(oid, NULL, &buffer_len) )
{
printf("error detected!\n");
#if defined(_WIN32) || defined(_WIN64)
system("pause");
#endif
return (-1);
}
printf("OID ASN.1 encode length is %d bytes.\n", buffer_len); if ( !(buffer = (unsigned char *)malloc(buffer_len)) )
{
printf("invoke malloc() function failed!\n");
#if defined(_WIN32) || defined(_WIN64)
system("pause");
#endif
return (-1);
} if ( Asn1EncodeOid(oid, buffer, &buffer_len) )
{
printf("error detected!\n");
free(buffer);
#if defined(_WIN32) || defined(_WIN64)
system("pause");
#endif
return (-1);
}
printf("OID ASN.1 encode:\n");
for (i=0; i<buffer_len; i++)
printf("0x%x ", buffer[i]);
printf("\n"); free(buffer);
#if defined(_WIN32) || defined(_WIN64)
system("pause");
#endif
return 0;
}
ASN.1 encode of SHA-256 is obtained from the demo: 0x6 0x9 0x60 0x86 0x48 0x1 0x65 0x3 0x4 0x2 0x1
This is a better implementation.
版权声明:本文博客原创文章,博客,未经同意,不得转载。
ASN.1 Encode an Object Identifier (OID) with OpenSSL的更多相关文章
- PostgreSQL中的Object Identifier(oid)数据类型
PostgreSQL在内部使用对象标识符(OID)作为各种系统表的主键.OID不会添加到用户创建的表中,除非在创建表时指定了WITH OIDS,或者启用了default_with_oids配置变量.类 ...
- Get RSA public key ASN.1 encode from a certificate in DER format
RSA public key ASN.1 encode is defined in PKCS#1 as follows: RSAPublicKey :: = SEQUENCE { modul ...
- oracle impdp ORA-02304 invalid object identifier literal
reference: https://webgeest.blogspot.com/2015/07/ora-39083-ora-02304-on-impdp-datapump.html 解决方法 ...
- OID的编解码(即在报文中的体现)
先上干货: 我们常见到OID的地方是SNMP和MIB,实际上理论上所有对象都可以有自己的ID.已存在的ID可以在http://www.oid-info.com/查到.这些ID在报文里并非字符串或直接的 ...
- SNMP History and OID/MIB Tour
https://www.pei.com/snmp-history-oid-mib/ Description: This document describes a bit of history and ...
- ECC公钥格式详解
本文首先介绍公钥格式相关的若干概念/技术,随后以示例的方式剖析DER格式的ECC公钥,最后介绍如何使用Java生成.解析和使用ECC公钥. ASN.1 Abstract Syntax Notation ...
- Java & PHP & Javascript 通用 RSA 加密 解密 (长字符串)
系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理:然而由于系统与系统之间的开发语言不同. 本次需求是生成二维码是通过java生成,由p ...
- c# .NET RSA结合AES加密服务端和客户端请求数据
这几天空闲时间就想研究一下加密,环境是web程序,通过js请求后台返回数据,我想做的事js在发送请求前将数据加密,服务端收到后解密,待服务端处理完请求后,将处理结果加密返回给客户端,客户端在解密,于是 ...
- COM Error Code(HRESULT)部分摘录
Return value/code Description 0x00030200 STG_S_CONVERTED The underlying file was converted to compou ...
随机推荐
- MySQL 存储过程和函数(转)
概述 一提到存储过程可能就会引出另一个话题就是存储过程的优缺点,这里也不做讨论,一般别人问我我就这样回答你觉得它好你就用它.因为mysql中存储过程和函数的语法非常接近所以就放在一起,主要区别就是函数 ...
- ASP.NET回车提交事务
浅析ASP.NET回车提交事件[转] ASP.NET回车提交事件其实说到底并不是ASP.NET 的编程问题,却是关于html form 中的submit 按钮就是如何规划的具体讨论. 也可归于ASP. ...
- SQL集合运算 差集 并集 交
SQL-3标准中提供了三种对检索结果进行集合运算的命令:并集UNION:交集INTERSECT:差集EXCEPT(在Oracle中叫做 MINUS).在有些数据库中对此的支持不够充分,如MySql中只 ...
- python 凸包(经纬度) + 面积[近似]
def cross(A,B): return A[0] * B[1] - A[1] * B[0] def vectorMinus( a , b): return ( (a[0] - b[0] )*10 ...
- 【Android开发经验】使用反射,得到的类的字段、方法、并实现了简单的调用
本文后推出Android的ICO框架做准备,所以,假设你想要一个最近的一项研究Android的ICO学生框架.你可以稍微看一下. 首先,简介一下Java里面的反射. JAVA反射机制是在执行状态中,对 ...
- POJ1469_COURSES(二部图最大匹配)
解决报告 http://blog.csdn.net/juncoder/article/details/38136065 题目传送门 题意: n个学生p门课程,每一个学生学习0或1以上的课程. 问:能否 ...
- 阿里游戏大数据sesson2_RF&GBRT(上)
----------一个小的游戏体验,对于不太熟悉Xlab RF和GBRT同学们都叫参考,不喜勿喷,大神绕道,米姆达. . .. .---------- 6月初的时候LR 做到4.9后一直上不去,看群 ...
- Case learning
bad case: <?php foreach($user_detail AS $val) { if(!empty($val->portrait)) { //假设这个循环从来没有到达过 $ ...
- 长方柱类【C++ 类定义】
Description 编写基于对象的程序,求长方柱(Bulk)的体积.数据成员包括长(length).宽(width).高(heigth).体积,要求用成员函数实现下面的功能: (1)由键盘输入长方 ...
- Metatable和Metamethod(转)
Metatable和Metamethod是用来干啥的?它们可以使得表a和b的表达式“a + b”变得有意义,其中metatable使两个不相关的表a和b之间可以进行操作,而操作的具体行为比如说&quo ...