mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 21:29:49 +00:00
ASN.1 BER support, with pF[apx] (#11517)
This commit is contained in:
parent
d389cd4468
commit
899719389f
@ -113,7 +113,8 @@ static char *signature (RBinFile *bf, bool json) {
|
||||
r_json_var_free (json);
|
||||
return c;
|
||||
}
|
||||
return r_pkcs7_cms_dump (bin->cms);
|
||||
r_pkcs7_cms_dump (bin->cms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static RList *fields(RBinFile *bf) {
|
||||
|
@ -902,16 +902,25 @@ static void cmd_print_fromage(RCore *core, const char *input, const ut8* data, i
|
||||
case '?': // "pF?"
|
||||
r_core_cmd_help (core, help_msg_pF);
|
||||
break;
|
||||
case 'o': // "pFo" asn1 oid
|
||||
case 'a':
|
||||
{
|
||||
RASN1Object *asn1 = r_asn1_create_object (data, size);
|
||||
if (asn1) {
|
||||
RASN1String *str1 = r_asn1_stringify_oid (data, size);
|
||||
if (str1) {
|
||||
r_cons_printf ("%s\n", str1->string);
|
||||
r_asn1_free_string (str1);
|
||||
}
|
||||
r_asn1_print_object (asn1, 0);
|
||||
r_asn1_free_object (asn1);
|
||||
} else {
|
||||
eprintf ("Malformed object: did you supply enough data?\ntry to change the block size (see b?)\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'x': // "pFx" x509
|
||||
{
|
||||
RX509Certificate* x509 = r_x509_parse_certificate (r_asn1_create_object (data, size));
|
||||
if (x509) {
|
||||
r_x509_certificate_dump (x509, NULL);
|
||||
r_x509_free_certificate (x509);
|
||||
} else {
|
||||
eprintf ("Malformed object: did you supply enough data?\ntry to change the block size (see b?)\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -919,12 +928,10 @@ static void cmd_print_fromage(RCore *core, const char *input, const ut8* data, i
|
||||
{
|
||||
RCMS *cms = r_pkcs7_parse_cms (data, size);
|
||||
if (cms) {
|
||||
char* foo = r_pkcs7_cms_dump (cms);
|
||||
if (foo) {
|
||||
r_cons_printf ("%s\n", foo);
|
||||
free (foo);
|
||||
}
|
||||
r_pkcs7_cms_dump (cms);
|
||||
r_pkcs7_free_cms (cms);
|
||||
} else {
|
||||
eprintf ("Malformed object: did you supply enough data?\ntry to change the block size (see b?)\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -78,6 +78,7 @@ typedef struct r_asn1_object_t {
|
||||
ut8 klass; /* class type */
|
||||
ut8 form; /* defines if contains data or objects */
|
||||
ut8 tag; /* tag type */
|
||||
ut8 undefined; /* set to != 0 if len is undefined */
|
||||
const ut8 *sector; /* Sector containg data */
|
||||
ut32 length; /* Sector Length */
|
||||
ASN1List list; /* List of objects contained in the sector */
|
||||
@ -93,10 +94,9 @@ R_API RASN1String *r_asn1_stringify_string (const ut8 *buffer, ut32 length);
|
||||
R_API RASN1String *r_asn1_stringify_bytes (const ut8 *buffer, ut32 length);
|
||||
R_API RASN1String *r_asn1_stringify_boolean (const ut8 *buffer, ut32 length);
|
||||
R_API RASN1String *r_asn1_stringify_oid (const ut8* buffer, ut32 length);
|
||||
R_API RASN1String *r_asn1_stringify_tag (RASN1Object *object);
|
||||
R_API RASN1String *r_asn1_stringify_object (RASN1Object *object);
|
||||
|
||||
R_API void r_asn1_free_object (RASN1Object *object);
|
||||
R_API void r_asn1_print_object (RASN1Object *object, ut32 depth);
|
||||
R_API void r_asn1_free_string (RASN1String *string);
|
||||
R_API void r_asn1_free_binary (RASN1Binary *string);
|
||||
|
||||
|
@ -71,7 +71,7 @@ typedef struct r_pkcs7_container_t {
|
||||
|
||||
R_API RCMS *r_pkcs7_parse_cms(const ut8 *buffer, ut32 length);
|
||||
R_API void r_pkcs7_free_cms(RCMS* container);
|
||||
R_API char* r_pkcs7_cms_dump(RCMS* container);
|
||||
R_API void r_pkcs7_cms_dump(RCMS* container);
|
||||
R_API RJSVar *r_pkcs7_cms_json(RCMS* container);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -68,6 +68,7 @@ R_API char *r_str_new(const char *str);
|
||||
R_API int r_snprintf (char *string, int len, const char *fmt, ...);
|
||||
R_API bool r_str_is_ascii(const char *str);
|
||||
R_API int r_str_is_printable(const char *str);
|
||||
R_API int r_str_is_printable_limited(const char *str, int size);
|
||||
R_API bool r_str_is_printable_incl_newlines(const char *str);
|
||||
R_API char *r_str_appendlen(char *ptr, const char *string, int slen);
|
||||
R_API char *r_str_newf(const char *fmt, ...);
|
||||
|
@ -106,13 +106,13 @@ typedef struct r_x509_certificaterevocationlist {
|
||||
|
||||
R_API RX509CertificateRevocationList* r_x509_parse_crl(RASN1Object *object);
|
||||
R_API void r_x509_free_crl(RX509CertificateRevocationList *crl);
|
||||
R_API char* r_x509_crl_dump(RX509CertificateRevocationList *crl, char* buffer, ut32 length, const char* pad);
|
||||
R_API void r_x509_crl_dump(RX509CertificateRevocationList *crl, const char* pad);
|
||||
R_API RJSVar *r_x509_crl_json(RX509CertificateRevocationList *crl);
|
||||
|
||||
R_API RX509Certificate *r_x509_parse_certificate(RASN1Object *object);
|
||||
R_API RX509Certificate *r_x509_parse_certificate2(const ut8 *buffer, ut32 length);
|
||||
R_API void r_x509_free_certificate(RX509Certificate* certificate);
|
||||
R_API char* r_x509_certificate_dump(RX509Certificate* certificate, char* buffer, ut32 length, const char* pad);
|
||||
R_API void r_x509_certificate_dump(RX509Certificate* certificate, const char* pad);
|
||||
R_API RJSVar* r_x509_certificate_json(RX509Certificate *certificate);
|
||||
|
||||
|
||||
|
214
libr/util/asn1.c
214
libr/util/asn1.c
@ -1,11 +1,31 @@
|
||||
/* radare2 - LGPL - Copyright 2017-2018 - wargio */
|
||||
|
||||
#include <r_util.h>
|
||||
#include <r_cons.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static RASN1Object *asn1_parse_header (const ut8 *buffer, ut32 length) {
|
||||
static ut32 asn1_ber_indefinite (const ut8 *buffer, ut32 length) {
|
||||
if (!length || !buffer) {
|
||||
return 0;
|
||||
}
|
||||
const ut8* next = buffer + 2;
|
||||
const ut8* end = buffer + (length - 3);
|
||||
while (next < end) {
|
||||
if (!next[0] && !next[1]) {
|
||||
break;
|
||||
}
|
||||
if (next[0] == 0x80 && (next[-1] & ASN1_FORM) == FORM_CONSTRUCTED) {
|
||||
next --;
|
||||
next += asn1_ber_indefinite (next, end - next);
|
||||
}
|
||||
next ++;
|
||||
}
|
||||
return (next - buffer) + 2;
|
||||
}
|
||||
|
||||
RASN1Object *asn1_parse_header (const ut8 *buffer, ut32 length) {
|
||||
ut8 head, length8, byte;
|
||||
ut64 length64;
|
||||
if (!buffer || length < 2) {
|
||||
@ -20,10 +40,12 @@ static RASN1Object *asn1_parse_header (const ut8 *buffer, ut32 length) {
|
||||
object->klass = head & ASN1_CLASS;
|
||||
object->form = head & ASN1_FORM;
|
||||
object->tag = head & ASN1_TAG;
|
||||
object->undefined = 0;
|
||||
length8 = buffer[1];
|
||||
if (length8 & ASN1_LENLONG) {
|
||||
length64 = 0;
|
||||
length8 &= ASN1_LENSHORT;
|
||||
object->sector = buffer + 2;
|
||||
if (length8 && length8 < length - 2) {
|
||||
ut8 i8;
|
||||
// can overflow.
|
||||
@ -35,27 +57,16 @@ static RASN1Object *asn1_parse_header (const ut8 *buffer, ut32 length) {
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
object->sector = buffer + 2 + length8;
|
||||
object->sector += length8;
|
||||
} else {
|
||||
//indefinite
|
||||
const ut8 *from = buffer + 2;
|
||||
const ut8 *end = from + (length - 2);
|
||||
do {
|
||||
byte = *from;
|
||||
length64 <<= 8;
|
||||
length64 |= byte;
|
||||
from++;
|
||||
} while (from < end && length64 <= length && byte & 0x80);
|
||||
if (length64 > length) {
|
||||
goto out_error;
|
||||
}
|
||||
object->sector = from;
|
||||
length64 = asn1_ber_indefinite (object->sector, length - 2);
|
||||
}
|
||||
object->length = (ut32) length64;
|
||||
} else {
|
||||
object->length = (ut32) length8;
|
||||
object->sector = buffer + 2;
|
||||
}
|
||||
|
||||
if (object->tag == TAG_BITSTRING && object->sector[0] == 0) {
|
||||
if (object->length > 0){
|
||||
object->sector++; //real sector starts +1
|
||||
@ -149,6 +160,179 @@ R_API RASN1Binary *r_asn1_create_binary (const ut8 *buffer, ut32 length) {
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
||||
R_API void r_asn1_print_hex (RASN1Object *object, char* buffer, ut32 size) {
|
||||
ut32 i;
|
||||
if (!object || !object->sector) {
|
||||
return;
|
||||
}
|
||||
char* p = buffer;
|
||||
char* end = buffer + size;
|
||||
for (i = 0; i < object->length && p < end; ++i) {
|
||||
snprintf (p, end - p, "%02x", object->sector[i]);
|
||||
p += 2;
|
||||
}
|
||||
if (p >= end) {
|
||||
p -= 4;
|
||||
snprintf (p, end - p, "...");
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_asn1_print_object (RASN1Object *object, ut32 depth) {
|
||||
ut32 i;
|
||||
if (!object) {
|
||||
return;
|
||||
}
|
||||
//this shall not be freed. it's a pointer into the buffer.
|
||||
RASN1String* asn1str = NULL;
|
||||
static char temp_name[256] = {0};
|
||||
const char* name = "";
|
||||
const char* string = "";
|
||||
memset (temp_name, 0, sizeof (temp_name));
|
||||
|
||||
switch (object->klass) {
|
||||
case CLASS_UNIVERSAL: // universal
|
||||
switch (object->tag) {
|
||||
case TAG_EOC:
|
||||
name = "EOC";
|
||||
break;
|
||||
case TAG_BOOLEAN:
|
||||
name = "BOOLEAN";
|
||||
if (object->sector) {
|
||||
string = (object->sector[0] != 0) ? "true" : "false";
|
||||
}
|
||||
break;
|
||||
case TAG_INTEGER:
|
||||
name = "INTEGER";
|
||||
r_asn1_print_hex (object, temp_name, 20);
|
||||
string = temp_name;
|
||||
break;
|
||||
case TAG_BITSTRING:
|
||||
name = "BIT_STRING";
|
||||
r_asn1_print_hex (object, temp_name, 20);
|
||||
string = temp_name;
|
||||
break;
|
||||
case TAG_OCTETSTRING:
|
||||
name = "OCTET_STRING";
|
||||
if (r_str_is_printable_limited (object->sector, object->length)) {
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
} else if (!object->list.objects) {
|
||||
r_asn1_print_hex (object, temp_name, 20);
|
||||
string = temp_name;
|
||||
}
|
||||
break;
|
||||
case TAG_NULL:
|
||||
name = "NULL";
|
||||
break;
|
||||
case TAG_OID:
|
||||
name = "OBJECT_IDENTIFIER";
|
||||
asn1str = r_asn1_stringify_oid (object->sector, object->length);
|
||||
break;
|
||||
case TAG_OBJDESCRIPTOR:
|
||||
name = "ObjectDescriptor";
|
||||
break;
|
||||
case TAG_EXTERNAL:
|
||||
name = "EXTERNAL";
|
||||
break;
|
||||
case TAG_REAL:
|
||||
name = "REAL";
|
||||
r_asn1_print_hex (object, temp_name, 20);
|
||||
string = temp_name;
|
||||
break;
|
||||
case TAG_ENUMERATED:
|
||||
name = "ENUMERATED";
|
||||
break;
|
||||
case TAG_EMBEDDED_PDV:
|
||||
name = "EMBEDDED_PDV";
|
||||
break;
|
||||
case TAG_UTF8STRING:
|
||||
name = "UTF8String";
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_SEQUENCE:
|
||||
name = "SEQUENCE";
|
||||
break;
|
||||
case TAG_SET:
|
||||
name = "SET";
|
||||
break;
|
||||
case TAG_NUMERICSTRING:
|
||||
name = "NumericString";
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_PRINTABLESTRING:
|
||||
name = "PrintableString"; // ASCII subset
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_T61STRING:
|
||||
name = "TeletexString"; // aka T61String
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_VIDEOTEXSTRING:
|
||||
name = "VideotexString";
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_IA5STRING:
|
||||
name = "IA5String"; // ASCII
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_UTCTIME:
|
||||
name = "UTCTime";
|
||||
asn1str = r_asn1_stringify_utctime (object->sector, object->length);
|
||||
break;
|
||||
case TAG_GENERALIZEDTIME:
|
||||
name = "GeneralizedTime";
|
||||
asn1str = r_asn1_stringify_time (object->sector, object->length);
|
||||
break;
|
||||
case TAG_GRAPHICSTRING:
|
||||
name = "GraphicString";
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_VISIBLESTRING:
|
||||
name = "VisibleString"; // ASCII subset
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_GENERALSTRING:
|
||||
name = "GeneralString";
|
||||
break;
|
||||
case TAG_UNIVERSALSTRING:
|
||||
name = "UniversalString";
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
case TAG_BMPSTRING:
|
||||
name = "BMPString";
|
||||
asn1str = r_asn1_stringify_string (object->sector, object->length);
|
||||
break;
|
||||
default:
|
||||
snprintf (temp_name, sizeof (temp_name), "Universal_%u", object->tag);
|
||||
name = temp_name;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CLASS_APPLICATION:
|
||||
snprintf (temp_name, sizeof (temp_name), "Application_%u", object->tag);
|
||||
name = temp_name;
|
||||
break;
|
||||
case CLASS_CONTEXT:
|
||||
snprintf (temp_name, sizeof (temp_name), "Context [%u]", object->tag); // Context
|
||||
name = temp_name;
|
||||
break;
|
||||
case CLASS_PRIVATE:
|
||||
snprintf (temp_name, sizeof (temp_name), "Private_%u", object->tag);
|
||||
name = temp_name;
|
||||
break;
|
||||
}
|
||||
if (asn1str) {
|
||||
string = asn1str->string;
|
||||
}
|
||||
r_cons_printf ("%4u:%2d: %s %-20s: %s\n", object->length, depth, object->form ? "cons" : "prim", name, string);
|
||||
r_asn1_free_string (asn1str);
|
||||
if (object->list.objects) {
|
||||
for (i = 0; i < object->list.length; ++i) {
|
||||
r_asn1_print_object (object->list.objects[i], depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_asn1_free_object (RASN1Object *object) {
|
||||
ut32 i;
|
||||
if (!object) {
|
||||
|
@ -590,14 +590,14 @@ struct r_oid_list_t {
|
||||
{"1.2.840.113549.1.5.13", "pkcs5PBES2"},
|
||||
{"1.2.840.113549.1.5.14", "pkcs5PBMAC1"},
|
||||
{"1.2.840.113549.1.7", "pkcs-7"},
|
||||
{"1.2.840.113549.1.7.1", "data"},
|
||||
{"1.2.840.113549.1.7.2", "signedData"},
|
||||
{"1.2.840.113549.1.7.3", "envelopedData"},
|
||||
{"1.2.840.113549.1.7.4", "signedAndEnvelopedData"},
|
||||
{"1.2.840.113549.1.7.5", "digestedData"},
|
||||
{"1.2.840.113549.1.7.6", "encryptedData"},
|
||||
{"1.2.840.113549.1.7.7", "dataWithAttributes"},
|
||||
{"1.2.840.113549.1.7.8", "encryptedPrivateKeyInfo"},
|
||||
{"1.2.840.113549.1.7.1", "pkcs-7-data"},
|
||||
{"1.2.840.113549.1.7.2", "pkcs-7-signedData"},
|
||||
{"1.2.840.113549.1.7.3", "pkcs-7-envelopedData"},
|
||||
{"1.2.840.113549.1.7.4", "pkcs-7-signedAndEnvelopedData"},
|
||||
{"1.2.840.113549.1.7.5", "pkcs-7-digestedData"},
|
||||
{"1.2.840.113549.1.7.6", "pkcs-7-encryptedData"},
|
||||
{"1.2.840.113549.1.7.7", "pkcs-7-dataWithAttributes"},
|
||||
{"1.2.840.113549.1.7.8", "pkcs-7-encryptedPrivateKeyInfo"},
|
||||
{"1.2.840.113549.1.9", "pkcs-9"},
|
||||
{"1.2.840.113549.1.9.1", "emailAddress"},
|
||||
{"1.2.840.113549.1.9.2", "unstructuredName"},
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <r_util.h>
|
||||
#include <r_cons.h>
|
||||
#include "./x509.h"
|
||||
|
||||
extern RJSVar *r_x509_name_json (RX509Name* name);
|
||||
@ -270,16 +271,18 @@ static bool r_pkcs7_parse_signeddata (RPKCS7SignedData *sd, RASN1Object *object)
|
||||
memset (sd, 0, sizeof (RPKCS7SignedData));
|
||||
RASN1Object **elems = object->list.objects;
|
||||
//Following RFC
|
||||
sd->version = (ut32) elems[0]->sector[0];
|
||||
sd->version = (ut32) elems[0]->sector[0];
|
||||
r_pkcs7_parse_digestalgorithmidentifier (&sd->digestAlgorithms, elems[1]);
|
||||
r_pkcs7_parse_contentinfo (&sd->contentInfo, elems[2]);
|
||||
//Optional
|
||||
if (shift < object->list.length && elems[shift] && elems[shift]->klass == CLASS_CONTEXT && elems[shift]->tag == 0) {
|
||||
if (object->list.length > 3 && shift < object->list.length && elems[shift] &&
|
||||
elems[shift]->klass == CLASS_CONTEXT && elems[shift]->tag == 0) {
|
||||
r_pkcs7_parse_extendedcertificatesandcertificates (&sd->certificates, elems[shift]);
|
||||
shift++;
|
||||
}
|
||||
//Optional
|
||||
if (shift < object->list.length && elems[shift] && elems[shift]->klass == CLASS_CONTEXT && elems[shift]->tag == 1) {
|
||||
if (object->list.length > 3 && shift < object->list.length && elems[shift] &&
|
||||
elems[shift]->klass == CLASS_CONTEXT && elems[shift]->tag == 1) {
|
||||
r_pkcs7_parse_certificaterevocationlists (&sd->crls, elems[shift]);
|
||||
shift++;
|
||||
}
|
||||
@ -311,9 +314,9 @@ R_API RCMS *r_pkcs7_parse_cms (const ut8 *buffer, ut32 length) {
|
||||
return NULL;
|
||||
}
|
||||
object = r_asn1_create_object (buffer, length);
|
||||
if (!object || object->list.length != 2 || !object->list.objects ||
|
||||
if (!object || object->list.length < 2 || !object->list.objects ||
|
||||
!object->list.objects[0] || !object->list.objects[1] ||
|
||||
object->list.objects[1]->list.length != 1) {
|
||||
object->list.objects[1]->list.length < 1) {
|
||||
r_asn1_free_object (object);
|
||||
free (container);
|
||||
return NULL;
|
||||
@ -377,252 +380,127 @@ static bool r_pkcs7_parse_attributes (RPKCS7Attributes* attributes, RASN1Object
|
||||
return true;
|
||||
}
|
||||
|
||||
char* r_pkcs7_signerinfos_dump (RX509CertificateRevocationList *crl, char* buffer, ut32 length, const char* pad) {
|
||||
void r_pkcs7_signerinfos_dump (RX509CertificateRevocationList *crl, const char* pad) {
|
||||
RASN1String *algo = NULL, *last = NULL, *next = NULL;
|
||||
ut32 i, p;
|
||||
int r;
|
||||
char *tmp, *pad2, *pad3;
|
||||
if (!crl || !buffer || !length) {
|
||||
return NULL;
|
||||
ut32 i;
|
||||
char *pad2, *pad3;
|
||||
if (!crl) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
pad3 = r_str_newf ("%s ", pad);
|
||||
if (!pad3) {
|
||||
return NULL;
|
||||
}
|
||||
if (!pad3) return;
|
||||
|
||||
pad2 = pad3 + 2;
|
||||
algo = crl->signature.algorithm;
|
||||
last = crl->lastUpdate;
|
||||
next = crl->nextUpdate;
|
||||
r = snprintf (buffer, length, "%sCRL:\n%sSignature:\n%s%s\n%sIssuer\n",
|
||||
pad, pad2, pad3, algo ? algo->string : "", pad2);
|
||||
p = (ut32) r;
|
||||
if (r < 0 || !(tmp = r_x509_name_dump (&crl->issuer, buffer + p, length - p, pad3))) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
if (length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sLast Update: %s\n%sNext Update: %s\n%sRevoked Certificates:\n",
|
||||
r_cons_printf ("%sCRL:\n%sSignature:\n%s%s\n%sIssuer\n", pad, pad2, pad3, algo ? algo->string : "", pad2);
|
||||
r_x509_name_dump (&crl->issuer, pad3);
|
||||
r_cons_printf ("%sLast Update: %s\n%sNext Update: %s\n%sRevoked Certificates:\n",
|
||||
pad2, last ? last->string : "Missing",
|
||||
pad2, next ? next->string : "Missing", pad2);
|
||||
p += (ut32) r;
|
||||
if (r < 0) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < crl->length; ++i) {
|
||||
if (length <= p || !(tmp = r_x509_crlentry_dump (crl->revokedCertificates[i], buffer + p, length - p, pad3))) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
r_x509_crlentry_dump (crl->revokedCertificates[i], pad3);
|
||||
}
|
||||
|
||||
free (pad3);
|
||||
return buffer + p;
|
||||
}
|
||||
|
||||
static char* r_x509_signedinfo_dump (RPKCS7SignerInfo *si, char* buffer, ut32 length, const char* pad) {
|
||||
static void r_x509_signedinfo_dump (RPKCS7SignerInfo *si, const char* pad) {
|
||||
RASN1String *s = NULL;
|
||||
RASN1Binary *o = NULL;
|
||||
ut32 i, p;
|
||||
int r;
|
||||
char *tmp, *pad2, *pad3;
|
||||
if (!si || !buffer || !length) {
|
||||
return NULL;
|
||||
ut32 i;
|
||||
char *pad2, *pad3;
|
||||
if (!si) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
pad3 = r_str_newf ("%s ", pad);
|
||||
if (!pad3) {
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
pad2 = pad3 + 2;
|
||||
|
||||
|
||||
r = snprintf (buffer, length, "%sSignerInfo:\n%sVersion: v%u\n%sIssuer\n", pad, pad2, si->version + 1, pad2);
|
||||
p = (ut32) r;
|
||||
if (r < 0) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (length <= p || !(tmp = r_x509_name_dump (&si->issuerAndSerialNumber.issuer, buffer + p, length - p, pad3))) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
r_cons_printf ("%sSignerInfo:\n%sVersion: v%u\n%sIssuer\n", pad, pad2, si->version + 1, pad2);
|
||||
r_x509_name_dump (&si->issuerAndSerialNumber.issuer, pad3);
|
||||
if ((o = si->issuerAndSerialNumber.serialNumber)) {
|
||||
s = r_asn1_stringify_integer (o->binary, o->length);
|
||||
} else {
|
||||
s = NULL;
|
||||
}
|
||||
if (length <= p) {
|
||||
free (pad3);
|
||||
r_asn1_free_string (s);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sSerial Number:\n%s%s\n", pad2, pad3, s ? s->string : "Missing");
|
||||
p += (ut32) r;
|
||||
r_cons_printf ("%sSerial Number:\n%s%s\n", pad2, pad3, s ? s->string : "Missing");
|
||||
r_asn1_free_string (s);
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = si->digestAlgorithm.algorithm;
|
||||
r = snprintf (buffer + p, length - p, "%sDigest Algorithm:\n%s%s\n%sAuthenticated Attributes:\n",
|
||||
r_cons_printf ("%sDigest Algorithm:\n%s%s\n%sAuthenticated Attributes:\n",
|
||||
pad2, pad3, s ? s->string : "Missing", pad2);
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < si->authenticatedAttributes.length; ++i) {
|
||||
RPKCS7Attribute* attr = si->authenticatedAttributes.elements[i];
|
||||
if (!attr) {
|
||||
continue;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%s%s: %u bytes\n",
|
||||
pad3, attr->oid ? attr->oid->string : "Missing", attr->data ? attr->data->length : 0);
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
if (!attr) continue;
|
||||
r_cons_printf ("%s%s: %u bytes\n", pad3, attr->oid ? attr->oid->string : "Missing",
|
||||
attr->data ? attr->data->length : 0);
|
||||
}
|
||||
s = si->digestEncryptionAlgorithm.algorithm;
|
||||
if (length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sDigest Encryption Algorithm\n%s%s\n",
|
||||
pad2, pad3, s ? s->string : "Missing");
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
r_cons_printf ("%sDigest Encryption Algorithm\n%s%s\n", pad2, pad3, s ? s->string : "Missing");
|
||||
|
||||
|
||||
// if ((o = si->encryptedDigest)) s = r_asn1_stringify_bytes (o->binary, o->length);
|
||||
// else s = NULL;
|
||||
// r = snprintf (buffer + p, length - p, "%sEncrypted Digest: %u bytes\n%s\n", pad2, o ? o->length : 0, s ? s->string : "Missing");
|
||||
// p += (ut32) r;
|
||||
// r_cons_printf ("%sEncrypted Digest: %u bytes\n%s\n", pad2, o ? o->length : 0, s ? s->string : "Missing");
|
||||
// r_asn1_free_string (s);
|
||||
r = snprintf (buffer + p, length - p, "%sEncrypted Digest: %u bytes\n", pad2, o ? o->length : 0);
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sUnauthenticated Attributes:\n", pad2);
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
r_cons_printf ("%sEncrypted Digest: %u bytes\n", pad2, o ? o->length : 0);
|
||||
r_cons_printf ("%sUnauthenticated Attributes:\n", pad2);
|
||||
for (i = 0; i < si->unauthenticatedAttributes.length; ++i) {
|
||||
RPKCS7Attribute* attr = si->unauthenticatedAttributes.elements[i];
|
||||
if (!attr) {
|
||||
continue;
|
||||
}
|
||||
o = attr->data;
|
||||
r = snprintf (buffer + p, length - p, "%s%s: %u bytes\n",
|
||||
pad3, attr->oid ? attr->oid->string : "Missing", o ? o->length : 0);
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
r_cons_printf ("%s%s: %u bytes\n", pad3, attr->oid ? attr->oid->string : "Missing",
|
||||
o ? o->length : 0);
|
||||
}
|
||||
free (pad3);
|
||||
return buffer + p;
|
||||
}
|
||||
|
||||
char *r_pkcs7_cms_dump (RCMS* container) {
|
||||
void r_pkcs7_cms_dump (RCMS* container) {
|
||||
RPKCS7SignedData *sd;
|
||||
ut32 i, length, p = 0;
|
||||
int r;
|
||||
char *buffer = NULL, *tmp = NULL;
|
||||
ut32 i;
|
||||
if (!container) {
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
sd = &container->signedData;
|
||||
length = 2048 + (container->signedData.certificates.length * 1024);
|
||||
if(!length) {
|
||||
return NULL;
|
||||
}
|
||||
buffer = (char*) calloc (1, length);
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer, length, "signedData\n Version: %u\n Digest Algorithms:\n", sd->version);
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
r_cons_printf ("signedData\n Version: v%u\n Digest Algorithms:\n", sd->version);
|
||||
|
||||
if (container->signedData.digestAlgorithms.elements) {
|
||||
eprintf("aaa\n");
|
||||
for (i = 0; i < container->signedData.digestAlgorithms.length; ++i) {
|
||||
if (container->signedData.digestAlgorithms.elements[i]) {
|
||||
RASN1String *s = container->signedData.digestAlgorithms.elements[i]->algorithm;
|
||||
r = snprintf (buffer + p, length - p, " %s\n", s ? s->string : "Missing");
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
r_cons_printf (" %s\n", s ? s->string : "Missing");
|
||||
}
|
||||
}
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, " Certificates: %u\n", container->signedData.certificates.length);
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r_cons_printf (" Certificates: %u\n", container->signedData.certificates.length);
|
||||
|
||||
for (i = 0; i < container->signedData.certificates.length; ++i) {
|
||||
if (length <= p || !(tmp = r_x509_certificate_dump (container->signedData.certificates.elements[i], buffer + p, length - p, " "))) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
r_x509_certificate_dump (container->signedData.certificates.elements[i], " ");
|
||||
}
|
||||
|
||||
for (i = 0; i < container->signedData.crls.length; ++i) {
|
||||
if (length <= p || !(tmp = r_x509_crl_dump (container->signedData.crls.elements[i], buffer + p, length - p, " "))) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
if (length <= p) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, " SignerInfos:\n");
|
||||
p += (ut32) r;
|
||||
if (r < 0 || length <= p) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
r_x509_crl_dump (container->signedData.crls.elements[i], " ");
|
||||
}
|
||||
|
||||
r_cons_printf (" SignerInfos:\n");
|
||||
if (container->signedData.signerinfos.elements) {
|
||||
for (i = 0; i < container->signedData.signerinfos.length; ++i) {
|
||||
if (length <= p || !(tmp = r_x509_signedinfo_dump (container->signedData.signerinfos.elements[i], buffer + p, length - p, " "))) {
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
r_x509_signedinfo_dump (container->signedData.signerinfos.elements[i], " ");
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
RJSVar *r_x509_signedinfo_json (RPKCS7SignerInfo* si) {
|
||||
|
@ -1449,6 +1449,22 @@ R_API int r_str_is_printable(const char *str) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API int r_str_is_printable_limited(const char *str, int size) {
|
||||
while (size > 0 && *str) {
|
||||
int ulen = r_utf8_decode ((const ut8*)str, strlen (str), NULL);
|
||||
if (ulen > 1) {
|
||||
str += ulen;
|
||||
continue;
|
||||
}
|
||||
if (!IS_PRINTABLE (*str)) {
|
||||
return 0;
|
||||
}
|
||||
str++;
|
||||
size--;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API bool r_str_is_printable_incl_newlines(const char *str) {
|
||||
while (*str) {
|
||||
int ulen = r_utf8_decode ((const ut8*)str, strlen (str), NULL);
|
||||
|
266
libr/util/x509.c
266
libr/util/x509.c
@ -1,6 +1,7 @@
|
||||
/* radare2 - LGPL - Copyright 2017-2018 - wargio */
|
||||
|
||||
#include <r_util.h>
|
||||
#include <r_cons.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "./x509.h"
|
||||
@ -412,52 +413,38 @@ void r_x509_free_crl (RX509CertificateRevocationList *crl) {
|
||||
}
|
||||
}
|
||||
|
||||
char* r_x509_validity_dump (RX509Validity* validity, char* buffer, ut32 length, const char* pad) {
|
||||
if (!validity || !buffer || !length) {
|
||||
return NULL;
|
||||
void r_x509_validity_dump (RX509Validity* validity, const char* pad) {
|
||||
if (!validity) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
const char* b = validity->notBefore ? validity->notBefore->string : "Missing";
|
||||
const char* a = validity->notAfter ? validity->notAfter->string : "Missing";
|
||||
int p = snprintf (buffer, length, "%sNot Before: %s\n%sNot After: %s\n", pad, b, pad, a);
|
||||
return p < 0 ? NULL : buffer + (ut32) p;
|
||||
r_cons_printf ("%sNot Before: %s\n%sNot After: %s\n", pad, b, pad, a);
|
||||
}
|
||||
|
||||
char* r_x509_name_dump (RX509Name* name, char* buffer, ut32 length, const char* pad) {
|
||||
ut32 i, p, len;
|
||||
int r;
|
||||
char* c;
|
||||
if (!name || !buffer || !length) {
|
||||
return NULL;
|
||||
void r_x509_name_dump (RX509Name* name, const char* pad) {
|
||||
ut32 i;
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
len = length;
|
||||
c = buffer;
|
||||
for (i = 0, p = 0; i < name->length; ++i) {
|
||||
for (i = 0; i < name->length; ++i) {
|
||||
if (!name->oids[i] || !name->names[i]) {
|
||||
continue;
|
||||
}
|
||||
if (len <= p) {
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (c + p, len - p, "%s%s: %s\n", pad, name->oids[i]->string, name->names[i]->string);
|
||||
p += r;
|
||||
if (r < 0 || len < p) {
|
||||
return NULL;
|
||||
}
|
||||
r_cons_printf ("%s%s: %s\n", pad, name->oids[i]->string, name->names[i]->string);
|
||||
}
|
||||
return c + p;
|
||||
}
|
||||
|
||||
char* r_x509_subjectpublickeyinfo_dump (RX509SubjectPublicKeyInfo* spki, char* buffer, ut32 length, const char* pad) {
|
||||
int r;
|
||||
void r_x509_subjectpublickeyinfo_dump (RX509SubjectPublicKeyInfo* spki, const char* pad) {
|
||||
const char *a;
|
||||
if (!spki || !buffer || !length) {
|
||||
return NULL;
|
||||
if (!spki) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
@ -470,26 +457,21 @@ char* r_x509_subjectpublickeyinfo_dump (RX509SubjectPublicKeyInfo* spki, char* b
|
||||
// RASN1String* e = r_asn1_stringify_bytes (spki->subjectPublicKeyExponent->sector, spki->subjectPublicKeyExponent->length);
|
||||
// r = snprintf (buffer, length, "%sAlgorithm: %s\n%sModule: %s\n%sExponent: %u bytes\n%s\n", pad, a, pad, m->string,
|
||||
// pad, spki->subjectPublicKeyExponent->length - 1, e->string);
|
||||
r = snprintf (buffer, length, "%sAlgorithm: %s\n%sModule: %s\n%sExponent: %u bytes\n", pad, a, pad, m ? m->string : "Missing",
|
||||
r_cons_printf ("%sAlgorithm: %s\n%sModule: %s\n%sExponent: %u bytes\n", pad, a, pad, m ? m->string : "Missing",
|
||||
pad, spki->subjectPublicKeyExponent ? spki->subjectPublicKeyExponent->length - 1 : 0);
|
||||
r_asn1_free_string (m);
|
||||
// r_asn1_free_string (e);
|
||||
return r < 0 ? NULL : buffer + (ut32) r;
|
||||
}
|
||||
|
||||
char* r_x509_extensions_dump (RX509Extensions* exts, char* buffer, ut32 length, const char* pad) {
|
||||
ut32 i, p, len;
|
||||
int r;
|
||||
char* c;
|
||||
if (!exts || !buffer || !length) {
|
||||
return NULL;
|
||||
void r_x509_extensions_dump (RX509Extensions* exts, const char* pad) {
|
||||
ut32 i;
|
||||
if (!exts) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
len = length;
|
||||
c = buffer;
|
||||
for (i = 0, p = 0, r = 0; i < exts->length; ++i) {
|
||||
for (i = 0; i < exts->length; ++i) {
|
||||
//RASN1String *s;
|
||||
RX509Extension *e = exts->extensions[i];
|
||||
if (!e) {
|
||||
@ -497,38 +479,26 @@ char* r_x509_extensions_dump (RX509Extensions* exts, char* buffer, ut32 length,
|
||||
}
|
||||
//TODO handle extensions..
|
||||
//s = r_asn1_stringify_bytes (e->extnValue->sector, e->extnValue->length);
|
||||
if (len < p) {
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (c + p, len - p, "%s%s: %s\n%s%u bytes\n", pad,
|
||||
r_cons_printf ("%s%s: %s\n%s%u bytes\n", pad,
|
||||
e->extnID ? e->extnID->string : "Missing",
|
||||
e->critical ? "critical" : "",
|
||||
pad, e->extnValue ? e->extnValue->length : 0);
|
||||
p += r;
|
||||
//r_asn1_free_string (s);
|
||||
if (r < 0 || len <= p) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return c + p;
|
||||
}
|
||||
|
||||
char* r_x509_tbscertificate_dump (RX509TBSCertificate* tbsc, char* buffer, ut32 length, const char* pad) {
|
||||
void r_x509_tbscertificate_dump (RX509TBSCertificate* tbsc, const char* pad) {
|
||||
RASN1String *sid = NULL, *iid = NULL;
|
||||
char *pad2, *tmp;
|
||||
ut32 p;
|
||||
int r;
|
||||
if (!tbsc || !buffer || !length) {
|
||||
return NULL;
|
||||
char *pad2;
|
||||
if (!tbsc) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
pad2 = r_str_newf ("%s ", pad);
|
||||
if (!pad2) {
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer, length, "%sVersion: v%u\n"
|
||||
if (!pad2) return;
|
||||
r_cons_printf ("%sVersion: v%u\n"
|
||||
"%sSerial Number:\n%s %s\n"
|
||||
"%sSignature Algorithm:\n%s %s\n"
|
||||
"%sIssuer:\n",
|
||||
@ -536,140 +506,69 @@ char* r_x509_tbscertificate_dump (RX509TBSCertificate* tbsc, char* buffer, ut32
|
||||
pad, pad, tbsc->serialNumber ? tbsc->serialNumber->string : "Missing",
|
||||
pad, pad, tbsc->signature.algorithm ? tbsc->signature.algorithm->string : "Missing",
|
||||
pad);
|
||||
p = (ut32) r;
|
||||
if (r < 0 || length <= p || !(tmp = r_x509_name_dump (&tbsc->issuer, buffer + p, length - p, pad2))) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
if (length <= p) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sValidity:\n", pad);
|
||||
p += r;
|
||||
if (r < 0 || length <= p || !(tmp = r_x509_validity_dump (&tbsc->validity, buffer + p, length - p, pad2))) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sSubject:\n", pad);
|
||||
p += r;
|
||||
if (r < 0 || length <= p || !(tmp = r_x509_name_dump (&tbsc->subject, buffer + p, length - p, pad2))) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sSubject Public Key Info:\n", pad);
|
||||
p += r;
|
||||
if (r < 0 || length <= p ||
|
||||
!(tmp = r_x509_subjectpublickeyinfo_dump (&tbsc->subjectPublicKeyInfo, buffer + p, length - p, pad2))) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
r_x509_name_dump (&tbsc->issuer, pad2);
|
||||
|
||||
r_cons_printf ("%sValidity:\n", pad);
|
||||
r_x509_validity_dump (&tbsc->validity, pad2);
|
||||
|
||||
r_cons_printf ("%sSubject:\n", pad);
|
||||
r_x509_name_dump (&tbsc->subject, pad2);
|
||||
|
||||
r_cons_printf ("%sSubject Public Key Info:\n", pad);
|
||||
r_x509_subjectpublickeyinfo_dump (&tbsc->subjectPublicKeyInfo, pad2);
|
||||
|
||||
if (tbsc->issuerUniqueID) {
|
||||
iid = r_asn1_stringify_integer (tbsc->issuerUniqueID->binary, tbsc->issuerUniqueID->length);
|
||||
if (iid) {
|
||||
if (length <= p) {
|
||||
r_asn1_free_string (iid);
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sIssuer Unique ID:\n%s %s", pad, pad, iid->string);
|
||||
p += r;
|
||||
} else {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
r_cons_printf ("%sIssuer Unique ID:\n%s %s", pad, pad, iid->string);
|
||||
r_asn1_free_string (iid);
|
||||
}
|
||||
r_asn1_free_string (iid);
|
||||
}
|
||||
if (tbsc->subjectUniqueID) {
|
||||
sid = r_asn1_stringify_integer (tbsc->subjectUniqueID->binary, tbsc->subjectUniqueID->length);
|
||||
if (sid) {
|
||||
if (length <= p) {
|
||||
r_asn1_free_string (sid);
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sSubject Unique ID:\n%s %s", pad, pad, sid->string);
|
||||
p += r;
|
||||
} else {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
r_cons_printf ("%sSubject Unique ID:\n%s %s", pad, pad, sid->string);
|
||||
r_asn1_free_string (sid);
|
||||
}
|
||||
r_asn1_free_string (sid);
|
||||
}
|
||||
if (r < 0 || length <= p) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sExtensions:\n", pad);
|
||||
p += r;
|
||||
if (r < 0 || length <= p || !(tmp = r_x509_extensions_dump (&tbsc->extensions, buffer + p, length - p, pad2))) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r_cons_printf ("%sExtensions:\n", pad);
|
||||
r_x509_extensions_dump (&tbsc->extensions, pad2);
|
||||
free (pad2);
|
||||
return buffer + p;
|
||||
}
|
||||
|
||||
char* r_x509_certificate_dump (RX509Certificate* certificate, char* buffer, ut32 length, const char* pad) {
|
||||
void r_x509_certificate_dump (RX509Certificate* certificate, const char* pad) {
|
||||
// RASN1String *signature,
|
||||
RASN1String *algo = NULL;
|
||||
ut32 p;
|
||||
int r;
|
||||
char *tbsc, *pad2;
|
||||
if (!certificate || !buffer || !length) {
|
||||
return NULL;
|
||||
char *pad2;
|
||||
if (!certificate) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
pad2 = r_str_newf ("%s ", pad);
|
||||
if (!pad2) {
|
||||
return NULL;
|
||||
}
|
||||
if ((r = snprintf (buffer, length, "%sTBSCertificate:\n", pad)) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
p = (ut32) r;
|
||||
tbsc = r_x509_tbscertificate_dump (&certificate->tbsCertificate, buffer + p, length - p, pad2);
|
||||
p = tbsc - buffer;
|
||||
if (length <= p) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
r_cons_printf ("%sTBSCertificate:\n", pad);
|
||||
r_x509_tbscertificate_dump (&certificate->tbsCertificate, pad2);
|
||||
|
||||
algo = certificate->algorithmIdentifier.algorithm;
|
||||
// signature = r_asn1_stringify_bytes (certificate->signature->binary, certificate->signature->length);
|
||||
// r = snprintf (buffer + p, length - p, "%sAlgorithm:\n%s%s\n%sSignature: %u bytes\n%s\n",
|
||||
// r_cons_printf ("%sAlgorithm:\n%s%s\n%sSignature: %u bytes\n%s\n",
|
||||
// pad, pad2, algo ? algo->string : "",
|
||||
// pad, certificate->signature->length, signature ? signature->string : "");
|
||||
r = snprintf (buffer + p, length - p, "%sAlgorithm:\n%s%s\n%sSignature: %u bytes\n",
|
||||
r_cons_printf ("%sAlgorithm:\n%s%s\n%sSignature: %u bytes\n",
|
||||
pad, pad2, algo ? algo->string : "", pad, certificate->signature->length);
|
||||
if (r < 0) {
|
||||
free (pad2);
|
||||
return NULL;
|
||||
}
|
||||
p += (ut32) r;
|
||||
free (pad2);
|
||||
// r_asn1_free_string (signature);
|
||||
return buffer + p;
|
||||
}
|
||||
|
||||
char* r_x509_crlentry_dump (RX509CRLEntry *crle, char* buffer, ut32 length, const char* pad) {
|
||||
void r_x509_crlentry_dump (RX509CRLEntry *crle, const char* pad) {
|
||||
RASN1String *id = NULL, *utc = NULL;
|
||||
int r;
|
||||
if (!crle || !buffer || !length) {
|
||||
return NULL;
|
||||
if (!crle) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
@ -679,64 +578,43 @@ char* r_x509_crlentry_dump (RX509CRLEntry *crle, char* buffer, ut32 length, cons
|
||||
id = r_asn1_stringify_integer (crle->userCertificate->binary, crle->userCertificate->length);
|
||||
}
|
||||
|
||||
r = snprintf (buffer, length, "%sUser Certificate:\n%s %s\n"
|
||||
r_cons_printf ("%sUser Certificate:\n%s %s\n"
|
||||
"%sRevocation Date:\n%s %s\n",
|
||||
pad, pad, id ? id->string : "Missing",
|
||||
pad, pad, utc ? utc->string : "Missing");
|
||||
|
||||
r_asn1_free_string (id);
|
||||
return r < 0 ? NULL : buffer + (ut32) r;
|
||||
}
|
||||
|
||||
char* r_x509_crl_dump (RX509CertificateRevocationList *crl, char* buffer, ut32 length, const char* pad) {
|
||||
void r_x509_crl_dump (RX509CertificateRevocationList *crl, const char* pad) {
|
||||
RASN1String *algo = NULL, *last = NULL, *next = NULL;
|
||||
ut32 i, p;
|
||||
int r;
|
||||
char *tmp, *pad2, *pad3;
|
||||
if (!crl || !buffer || !length) {
|
||||
return NULL;
|
||||
ut32 i;
|
||||
char *pad2, *pad3;
|
||||
if (!crl) {
|
||||
return;
|
||||
}
|
||||
if (!pad) {
|
||||
pad = "";
|
||||
}
|
||||
pad3 = r_str_newf ("%s ", pad);
|
||||
if (!pad3) {
|
||||
return NULL;
|
||||
}
|
||||
if (!pad3) return;
|
||||
pad2 = pad3 + 2;
|
||||
algo = crl->signature.algorithm;
|
||||
last = crl->lastUpdate;
|
||||
next = crl->nextUpdate;
|
||||
r = snprintf (buffer, length, "%sCRL:\n%sSignature:\n%s%s\n%sIssuer\n",
|
||||
pad, pad2, pad3, algo ? algo->string : "", pad2);
|
||||
p = (ut32) r;
|
||||
if (r < 0 || !(tmp = r_x509_name_dump (&crl->issuer, buffer + p, length - p, pad3))) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
if (length <= p) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
r = snprintf (buffer + p, length - p, "%sLast Update: %s\n%sNext Update: %s\n%sRevoked Certificates:\n",
|
||||
r_cons_printf ("%sCRL:\n%sSignature:\n%s%s\n%sIssuer\n", pad, pad2, pad3,
|
||||
algo ? algo->string : "", pad2);
|
||||
r_x509_name_dump (&crl->issuer, pad3);
|
||||
|
||||
r_cons_printf ("%sLast Update: %s\n%sNext Update: %s\n%sRevoked Certificates:\n",
|
||||
pad2, last ? last->string : "Missing",
|
||||
pad2, next ? next->string : "Missing", pad2);
|
||||
p += (ut32) r;
|
||||
if (r < 0) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < crl->length; ++i) {
|
||||
if (length <= p || !(tmp = r_x509_crlentry_dump (crl->revokedCertificates[i], buffer + p, length - p, pad3))) {
|
||||
free (pad3);
|
||||
return NULL;
|
||||
}
|
||||
p = tmp - buffer;
|
||||
r_x509_crlentry_dump (crl->revokedCertificates[i], pad3);
|
||||
}
|
||||
|
||||
free (pad3);
|
||||
return buffer + p;
|
||||
}
|
||||
|
||||
RJSVar *r_x509_validity_json (RX509Validity* validity) {
|
||||
|
@ -22,12 +22,12 @@ R_API void r_x509_free_tbscertificate (RX509TBSCertificate * tbsc);
|
||||
R_API RX509CRLEntry *r_x509_parse_crlentry (RASN1Object *object);
|
||||
R_API void r_x509_free_crlentry (RX509CRLEntry *entry);
|
||||
|
||||
R_API char* r_x509_validity_dump (RX509Validity* validity, char* buffer, ut32 length, const char* pad);
|
||||
R_API char* r_x509_name_dump (RX509Name* name, char* buffer, ut32 length, const char* pad);
|
||||
R_API char* r_x509_subjectpublickeyinfo_dump (RX509SubjectPublicKeyInfo* spki, char* buffer, ut32 length, const char* pad);
|
||||
R_API char* r_x509_extensions_dump (RX509Extensions* exts, char* buffer, ut32 length, const char* pad);
|
||||
R_API char* r_x509_tbscertificate_dump (RX509TBSCertificate* tbsc, char* buffer, ut32 length, const char* pad);
|
||||
R_API char* r_x509_crlentry_dump (RX509CRLEntry *crle, char* buffer, ut32 length, const char* pad);
|
||||
R_API void r_x509_validity_dump (RX509Validity* validity, const char* pad);
|
||||
R_API void r_x509_name_dump (RX509Name* name, const char* pad);
|
||||
R_API void r_x509_subjectpublickeyinfo_dump (RX509SubjectPublicKeyInfo* spki, const char* pad);
|
||||
R_API void r_x509_extensions_dump (RX509Extensions* exts, const char* pad);
|
||||
R_API void r_x509_tbscertificate_dump (RX509TBSCertificate* tbsc, const char* pad);
|
||||
R_API void r_x509_crlentry_dump (RX509CRLEntry *crle, const char* pad);
|
||||
|
||||
#endif /* R_X509_INTERNAL_H */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user