print ASN.1 time and ASCII tranlation
This commit is contained in:
parent
8de544653c
commit
baa709ff74
|
@ -22,11 +22,12 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
|
@ -144,40 +145,79 @@ void sc_copy_asn1_entry(const struct sc_asn1_entry *src,
|
||||||
dest->name = NULL;
|
dest->name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sc_asn1_print_octet_string(const u8 * buf, size_t buflen)
|
static void print_indent(size_t depth)
|
||||||
{
|
{
|
||||||
size_t i;
|
for (; depth > 0; depth--) {
|
||||||
|
putchar(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < buflen; i++)
|
static void print_hex(const u8 * buf, size_t buflen, size_t depth)
|
||||||
printf("%02X", buf[i]);
|
{
|
||||||
|
size_t lines_len = buflen * 5 + 128;
|
||||||
|
char *lines = malloc(lines_len);
|
||||||
|
char *line = lines;
|
||||||
|
|
||||||
|
if (buf == NULL || buflen == 0 || lines == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sc_hex_dump(buf, buflen, lines, lines_len);
|
||||||
|
|
||||||
|
while (*line != '\0') {
|
||||||
|
char *line_end = strchr(line, '\n');
|
||||||
|
ptrdiff_t width = line_end - line;
|
||||||
|
if (!line_end || width <= 1) {
|
||||||
|
/* don't print empty lines */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buflen > 8) {
|
||||||
|
putchar('\n');
|
||||||
|
print_indent(depth);
|
||||||
|
} else {
|
||||||
|
printf(": ");
|
||||||
|
}
|
||||||
|
printf("%.*s", (int) width, line);
|
||||||
|
line = line_end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_ascii(const u8 * buf, size_t buflen)
|
||||||
|
{
|
||||||
|
for (; 0 < buflen; buflen--, buf++) {
|
||||||
|
if (isprint(*buf))
|
||||||
|
printf("%c", *buf);
|
||||||
|
else
|
||||||
|
putchar('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sc_asn1_print_octet_string(const u8 * buf, size_t buflen, size_t depth)
|
||||||
|
{
|
||||||
|
print_hex(buf, buflen, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sc_asn1_print_utf8string(const u8 * buf, size_t buflen)
|
static void sc_asn1_print_utf8string(const u8 * buf, size_t buflen)
|
||||||
{
|
{
|
||||||
size_t i;
|
/* FIXME UTF-8 is not ASCII */
|
||||||
|
print_ascii(buf, buflen);
|
||||||
for (i = 0; i < buflen; i++)
|
|
||||||
printf("%c", buf[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sc_asn1_print_integer(const u8 * buf, size_t buflen)
|
static void sc_asn1_print_integer(const u8 * buf, size_t buflen)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
size_t a = 0;
|
||||||
long long a = 0;
|
|
||||||
#else
|
|
||||||
__int64 a = 0;
|
|
||||||
#endif
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (buflen > sizeof(a)) {
|
if (buflen > sizeof(a)) {
|
||||||
printf("too long");
|
printf("0x%s", sc_dump_hex(buf, buflen));
|
||||||
return;
|
} else {
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < buflen; i++) {
|
||||||
|
a <<= 8;
|
||||||
|
a |= buf[i];
|
||||||
|
}
|
||||||
|
printf("%"SC_FORMAT_LEN_SIZE_T"u", a);
|
||||||
}
|
}
|
||||||
for (i = 0; i < buflen; i++) {
|
|
||||||
a <<= 8;
|
|
||||||
a |= buf[i];
|
|
||||||
}
|
|
||||||
printf("%lld", a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sc_asn1_print_boolean(const u8 * buf, size_t buflen)
|
static void sc_asn1_print_boolean(const u8 * buf, size_t buflen)
|
||||||
|
@ -191,7 +231,7 @@ static void sc_asn1_print_boolean(const u8 * buf, size_t buflen)
|
||||||
printf("false");
|
printf("false");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen)
|
static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen, size_t depth)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
long long a = 0;
|
long long a = 0;
|
||||||
|
@ -201,16 +241,16 @@ static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen)
|
||||||
int r, i;
|
int r, i;
|
||||||
|
|
||||||
if (buflen > sizeof(a) + 1) {
|
if (buflen > sizeof(a) + 1) {
|
||||||
printf("too long");
|
print_hex(buf, buflen, depth);
|
||||||
return;
|
} else {
|
||||||
}
|
r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a));
|
||||||
r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a));
|
if (r < 0) {
|
||||||
if (r < 0) {
|
printf("decode error");
|
||||||
printf("decode error");
|
return;
|
||||||
return;
|
}
|
||||||
}
|
for (i = r - 1; i >= 0; i--) {
|
||||||
for (i = r - 1; i >= 0; i--) {
|
printf("%c", ((a >> i) & 1) ? '1' : '0');
|
||||||
printf("%c", ((a >> i) & 1) ? '1' : '0');
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +263,7 @@ static void openssl_print_object_sn(const char *s)
|
||||||
if (obj) {
|
if (obj) {
|
||||||
int nid = OBJ_obj2nid(obj);
|
int nid = OBJ_obj2nid(obj);
|
||||||
if (nid != NID_undef) {
|
if (nid != NID_undef) {
|
||||||
printf("%s ", OBJ_nid2sn(nid));
|
printf(", %s", OBJ_nid2sn(nid));
|
||||||
}
|
}
|
||||||
ASN1_OBJECT_free(obj);
|
ASN1_OBJECT_free(obj);
|
||||||
}
|
}
|
||||||
|
@ -237,33 +277,71 @@ static void openssl_print_object_sn(const char *s)
|
||||||
static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
|
static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
|
||||||
{
|
{
|
||||||
struct sc_object_id oid;
|
struct sc_object_id oid;
|
||||||
int i = 0;
|
const char *sbuf;
|
||||||
char tmp[12];
|
|
||||||
char sbuf[(sizeof tmp)*SC_MAX_OBJECT_ID_OCTETS];
|
|
||||||
|
|
||||||
if (sc_asn1_decode_object_id(buf, buflen, &oid)) {
|
if (sc_asn1_decode_object_id(buf, buflen, &oid)) {
|
||||||
printf("decode error");
|
printf("decode error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sbuf[0] = 0;
|
sbuf = sc_dump_oid(&oid);
|
||||||
for (i = 0; (i < SC_MAX_OBJECT_ID_OCTETS) && (oid.value[i] != -1); i++) {
|
printf(" %s", sbuf);
|
||||||
|
openssl_print_object_sn(sbuf);
|
||||||
|
}
|
||||||
|
|
||||||
if (i)
|
static void sc_asn1_print_utctime(const u8 * buf, size_t buflen)
|
||||||
strcat(sbuf, ".");
|
{
|
||||||
sprintf(tmp, "%d", oid.value[i]);
|
if (buflen < 8) {
|
||||||
strcat(sbuf, tmp);
|
printf("Error in decoding.\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
openssl_print_object_sn(sbuf);
|
print_ascii(buf, 2); /* YY */
|
||||||
printf("%s", sbuf);
|
putchar('-');
|
||||||
|
print_ascii(buf+2, 2); /* MM */
|
||||||
|
putchar('-');
|
||||||
|
print_ascii(buf+4, 2); /* DD */
|
||||||
|
putchar(' ');
|
||||||
|
print_ascii(buf+6, 2); /* hh */
|
||||||
|
buf += 8;
|
||||||
|
buflen -= 8;
|
||||||
|
if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
|
||||||
|
putchar(':');
|
||||||
|
print_ascii(buf, 2); /* mm */
|
||||||
|
buf += 2;
|
||||||
|
buflen -= 2;
|
||||||
|
}
|
||||||
|
if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
|
||||||
|
putchar(':');
|
||||||
|
print_ascii(buf, 2); /* ss */
|
||||||
|
buf += 2;
|
||||||
|
buflen -= 2;
|
||||||
|
}
|
||||||
|
if (buflen >= 4 && '.' == buf[0]) {
|
||||||
|
print_ascii(buf, 4); /* fff */
|
||||||
|
buf += 4;
|
||||||
|
buflen -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buflen >= 1 && 'Z' == buf[0]) {
|
||||||
|
printf(" UTC");
|
||||||
|
} else if (buflen >= 5 && ('-' == buf[0] || '+' == buf[0])) {
|
||||||
|
putchar(' ');
|
||||||
|
print_ascii(buf, 3); /* +/-hh */
|
||||||
|
putchar(':');
|
||||||
|
print_ascii(buf+3, 2); /* mm */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen)
|
static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen)
|
||||||
{
|
{
|
||||||
size_t ii;
|
if (buflen < 8) {
|
||||||
for (ii=0; ii<buflen; ii++)
|
printf("Error in decoding.\n");
|
||||||
printf("%c", *(buf + ii));
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_ascii(buf, 2);
|
||||||
|
sc_asn1_print_utctime(buf + 2, buflen - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
||||||
|
@ -295,9 +373,7 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
||||||
printf("Zero tag, finishing\n");
|
printf("Zero tag, finishing\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (i = 0; i < depth; i++) {
|
print_indent(depth);
|
||||||
putchar(' ');
|
|
||||||
}
|
|
||||||
/* let i be the length of the tag in bytes */
|
/* let i be the length of the tag in bytes */
|
||||||
for (i = 1; i < sizeof tag - 1; i++) {
|
for (i = 1; i < sizeof tag - 1; i++) {
|
||||||
if (!(tag >> 8*i))
|
if (!(tag >> 8*i))
|
||||||
|
@ -312,9 +388,12 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
||||||
classes[cla >> 6],
|
classes[cla >> 6],
|
||||||
i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i + 1) * 8));
|
i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i + 1) * 8));
|
||||||
}
|
}
|
||||||
printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)",
|
if (!((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL
|
||||||
len,
|
&& tag == SC_ASN1_TAG_NULL && len == 0)) {
|
||||||
len != 1 ? "s" : "");
|
printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)",
|
||||||
|
len,
|
||||||
|
len != 1 ? "s" : "");
|
||||||
|
}
|
||||||
|
|
||||||
if (len + hlen > bytesleft) {
|
if (len + hlen > bytesleft) {
|
||||||
printf(" Illegal length!\n");
|
printf(" Illegal length!\n");
|
||||||
|
@ -329,47 +408,54 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL
|
switch (tag) {
|
||||||
&& tag != SC_ASN1_TAG_NULL) {
|
|
||||||
printf(" [");
|
|
||||||
switch (tag) {
|
|
||||||
case SC_ASN1_TAG_BIT_STRING:
|
case SC_ASN1_TAG_BIT_STRING:
|
||||||
sc_asn1_print_bit_string(tagp, len);
|
printf(": ");
|
||||||
|
sc_asn1_print_bit_string(tagp, len, depth + 2*i + 1);
|
||||||
break;
|
break;
|
||||||
case SC_ASN1_TAG_OCTET_STRING:
|
case SC_ASN1_TAG_OCTET_STRING:
|
||||||
sc_asn1_print_octet_string(tagp, len);
|
sc_asn1_print_octet_string(tagp, len, depth + 2*i + 1);
|
||||||
break;
|
break;
|
||||||
case SC_ASN1_TAG_OBJECT:
|
case SC_ASN1_TAG_OBJECT:
|
||||||
|
printf(": ");
|
||||||
sc_asn1_print_object_id(tagp, len);
|
sc_asn1_print_object_id(tagp, len);
|
||||||
break;
|
break;
|
||||||
case SC_ASN1_TAG_INTEGER:
|
case SC_ASN1_TAG_INTEGER:
|
||||||
case SC_ASN1_TAG_ENUMERATED:
|
case SC_ASN1_TAG_ENUMERATED:
|
||||||
|
printf(": ");
|
||||||
sc_asn1_print_integer(tagp, len);
|
sc_asn1_print_integer(tagp, len);
|
||||||
break;
|
break;
|
||||||
case SC_ASN1_TAG_T61STRING:
|
case SC_ASN1_TAG_IA5STRING:
|
||||||
case SC_ASN1_TAG_PRINTABLESTRING:
|
case SC_ASN1_TAG_PRINTABLESTRING:
|
||||||
|
case SC_ASN1_TAG_T61STRING:
|
||||||
case SC_ASN1_TAG_UTF8STRING:
|
case SC_ASN1_TAG_UTF8STRING:
|
||||||
|
printf(": ");
|
||||||
sc_asn1_print_utf8string(tagp, len);
|
sc_asn1_print_utf8string(tagp, len);
|
||||||
break;
|
break;
|
||||||
case SC_ASN1_TAG_BOOLEAN:
|
case SC_ASN1_TAG_BOOLEAN:
|
||||||
|
printf(": ");
|
||||||
sc_asn1_print_boolean(tagp, len);
|
sc_asn1_print_boolean(tagp, len);
|
||||||
break;
|
break;
|
||||||
case SC_ASN1_GENERALIZEDTIME:
|
case SC_ASN1_GENERALIZEDTIME:
|
||||||
|
printf(": ");
|
||||||
sc_asn1_print_generalizedtime(tagp, len);
|
sc_asn1_print_generalizedtime(tagp, len);
|
||||||
break;
|
break;
|
||||||
}
|
case SC_ASN1_UTCTIME:
|
||||||
printf("]");
|
printf(": ");
|
||||||
|
sc_asn1_print_utctime(tagp, len);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION)
|
if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) {
|
||||||
printf(" [%s]", sc_dump_hex(tagp, len));
|
print_hex(tagp, len, depth + 2*i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT)
|
if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) {
|
||||||
printf(" [%s]", sc_dump_hex(tagp, len));
|
print_hex(tagp, len, depth + 2*i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc_asn1_print_tags(const u8 * buf, size_t buflen)
|
void sc_asn1_print_tags(const u8 * buf, size_t buflen)
|
||||||
|
|
Loading…
Reference in New Issue