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 ...
随机推荐
- Drupal 7 模 .info 文件描述
Drupal使用.info文件以节省话题(theme)和模块(modules)基本数据(metadata). 编码:推荐使用UTF-8.这是一个没有BOM(Byte Order Mark). 下面是一 ...
- c++程序代写(qq:928900200)
1. Both main memory and secondary storage are types of memory. Describe the difference between the ...
- 《HBase权威指南》读书笔记----简介
工作中要使用HBase,刚刚开始接触HBase,理解不深,只是记录一下 . HBase基于google的bigtable论文实现,属于nosql. 几个概念: (1)列(column):最基本单位为列 ...
- Android调试优化篇
为了开发出商业级的应用程序,大规模的測试是不可避免的,同一时候为了提高应用程序的执行速度,须要进行必要的优化.在Android中.提供了丰富的调试与优化工具供开发者应用,主要包含模拟器和目标端等两种场 ...
- 如何处理 Windows Phone 8 动态砖变成黑白砖
原文:如何处理 Windows Phone 8 动态砖变成黑白砖 ? 问题的来龙去脉 我的 Windows Phone 8 动态砖变成黑白砖,所有图示和文字变成黑白,该如何处理? ? 问题的发生原因 ...
- post跨域请求
[名词解释] 跨域:https://developer.mozilla.org/en-US/docs/JavaScript/Same_origin_policy_for_JavaScript 同源策略 ...
- CodeForces 484A Bits
意甲冠军: 10000询价 每次查询输入L和R(10^18) 在区间的二进制输出指示1大多数数字 1个数同样输出最小的 思路: YY一下 认为后几位全是1的时候能保证1的个数多 那么怎样构造 ...
- 开源通讯组件ec
跨平台开源通讯组件elastic communication elastic communication是基于c#开发支持.net和mono的通讯组件(简称EC),EC的主要目的简化mono和.net ...
- Java 解析 lnk 快捷方式文件的方法(转)
package file.extendsion; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.F ...
- Windows Auzre 微软的云计算产品的后台操作界面
Windows Auzre 微软的云计算产品的后台操作界面,试用期,相比于阿里云后台操作不是人. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTmFvbG ...