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 ...
随机推荐
- UNIX网络编程卷1 时间获取程序server TCP 协议相关性
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 最初代码: 这是一个简单的时间获取server程序.它和时间获取程序client一道工作. ...
- bzoj1001/BJOI2006 灰太狼抓到的兔子
1001: [BeiJing2006]狼抓兔子(id=1001">传送门) 图论新知识..没学过.. 平面图最小割等于对偶图的最短路 详见课件:http://wenku.baidu.c ...
- 关于AIX lv 4k offset问题初步了解
关于这个问题我们首先来看一下AIX的vg的3种类型: original vg 普通卷组 big vg 大卷组 scalable vg 动态的或者可扩展的卷组 如何快速区分这三组卷组呢? 通过其参数MA ...
- 冒泡排序java
先对冒泡排序做一个简单的解释,然后是代码的实现.解释出资<java的数据结构和算法>,大家可以看看. 排序类: package com.dxx.order; public class Bu ...
- c++ primer 函数传值1
不看c++ primer 永远不知道自己基础有多差 函数的參数传值一般有两种方式:值传递,引用传递. 值传递有以下两种形式: void func( int a ) { // } void func1 ...
- atitit..主流 浏览器 js 发动机 内核 市场份额 attialx总结vOa9
atitit..主流 浏览器 js 发动机 内核 市场份额 attialx总结vOa9 1. 浏览器内核 1 2. 浏览器的主要组件包含: 2 2.1. 主要组件体系结构 2 2.2. WebCor ...
- JavaEE SSH集成框架(两) struts2 本地加载dtd文件,action组态
1. 载入中struts2的dtd文件.使struts.xml网络无法验证,和eclipse有技巧 在src在创建struts.xml: <? xmlversion="1.0" ...
- 认识Require
1. 加载require.js文件 <script type="text/javascript" src="js/require.js" data-mai ...
- 每天努力一点之SQL
今天工作当中遇到一个问题:统计信息并导出EXcel 报表. 刚开始只做了统计信息: 如下图 请看最后一列的数据. 我当时想都从数据库里取出来,但是由于我能力有限没有做出来.先贴下后来写的SQL 语句. ...
- SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别
SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别: IN:确定给定的值是否与子查询或列表中的值相匹配. IN 关键字使您得以选择与列表中的任意一个值匹配的行. 当要获得居住在 ...