1 /* radare2 - LGPL - Copyright 2017-2018 - wargio */
2
3 #include <r_util.h>
4 #include <r_cons.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include "./x509.h"
8
r_x509_parse_validity(RX509Validity * validity,RASN1Object * object)9 static bool r_x509_parse_validity(RX509Validity *validity, RASN1Object *object) {
10 RASN1Object *o;
11 if (!validity || !object || object->list.length != 2) {
12 return false;
13 }
14 if (object->klass == CLASS_UNIVERSAL &&
15 object->tag == TAG_SEQUENCE &&
16 object->form == FORM_CONSTRUCTED) {
17 o = object->list.objects[0];
18 if (o->klass == CLASS_UNIVERSAL && o->form == FORM_PRIMITIVE) {
19 if (o->tag == TAG_UTCTIME) {
20 validity->notBefore = r_asn1_stringify_utctime (o->sector, o->length);
21 } else if (o->tag == TAG_GENERALIZEDTIME) {
22 validity->notBefore = r_asn1_stringify_time (o->sector, o->length);
23 }
24 }
25 o = object->list.objects[1];
26 if (o->klass == CLASS_UNIVERSAL && o->form == FORM_PRIMITIVE) {
27 if (o->tag == TAG_UTCTIME) {
28 validity->notAfter = r_asn1_stringify_utctime (o->sector, o->length);
29 } else if (o->tag == TAG_GENERALIZEDTIME) {
30 validity->notAfter = r_asn1_stringify_time (o->sector, o->length);
31 }
32 }
33 }
34 return true;
35 }
36
is_oid_object(RASN1Object * object)37 static inline bool is_oid_object (RASN1Object *object) {
38 return object->list.objects[0] &&
39 object->list.objects[0]->klass == CLASS_UNIVERSAL &&
40 object->list.objects[0]->tag == TAG_OID;
41 }
42
r_x509_parse_algorithmidentifier(RX509AlgorithmIdentifier * ai,RASN1Object * object)43 bool r_x509_parse_algorithmidentifier (RX509AlgorithmIdentifier *ai, RASN1Object *object) {
44 r_return_val_if_fail (ai && object, false);
45
46 if (object->list.length < 1 || !object->list.objects || !is_oid_object (object)) {
47 return false;
48 }
49
50 ai->algorithm = r_asn1_stringify_oid (object->list.objects[0]->sector, object->list.objects[0]->length);
51 ai->parameters = NULL; // TODO
52 //ai->parameters = asn1_stringify_sector (object->list.objects[1]);
53 return true;
54 }
55
r_x509_parse_subjectpublickeyinfo(RX509SubjectPublicKeyInfo * spki,RASN1Object * object)56 bool r_x509_parse_subjectpublickeyinfo (RX509SubjectPublicKeyInfo *spki, RASN1Object *object) {
57 RASN1Object *o;
58 if (!spki || !object || object->list.length != 2) {
59 return false;
60 }
61 r_x509_parse_algorithmidentifier (&spki->algorithm, object->list.objects[0]);
62 if (object->list.objects[1]) {
63 o = object->list.objects[1];
64 spki->subjectPublicKey = r_asn1_create_binary (o->sector, o->length);
65 if (o->list.length == 1 && o->list.objects[0] && o->list.objects[0]->list.length == 2) {
66 o = o->list.objects[0];
67 if (o->list.objects[0]) {
68 spki->subjectPublicKeyExponent = r_asn1_create_binary (o->list.objects[0]->sector, o->list.objects[0]->length);
69 }
70 if (o->list.objects[1]) {
71 spki->subjectPublicKeyModule = r_asn1_create_binary (o->list.objects[1]->sector, o->list.objects[1]->length);
72 }
73 }
74 }
75 return true;
76 }
77
r_x509_parse_name(RX509Name * name,RASN1Object * object)78 bool r_x509_parse_name (RX509Name *name, RASN1Object *object) {
79 ut32 i;
80 if (!name || !object || !object->list.length) {
81 return false;
82 }
83 if (object->klass == CLASS_UNIVERSAL && object->tag == TAG_SEQUENCE) {
84 name->length = object->list.length;
85 name->names = (RASN1String **)calloc (name->length, sizeof (RASN1String *));
86 if (!name->names) {
87 name->length = 0;
88 return false;
89 }
90 name->oids = (RASN1String **)calloc (name->length, sizeof (RASN1String *));
91 if (!name->oids) {
92 name->length = 0;
93 R_FREE (name->names);
94 return false;
95 }
96 for (i = 0; i < object->list.length; i++) {
97 RASN1Object *o = object->list.objects[i];
98 if (o && o->klass == CLASS_UNIVERSAL &&
99 o->tag == TAG_SET &&
100 o->form == FORM_CONSTRUCTED &&
101 o->list.length == 1) {
102 o = o->list.objects[0];
103 if (o && o->list.length > 1 &&
104 o->klass == CLASS_UNIVERSAL &&
105 o->tag == TAG_SEQUENCE) {
106 if (o->list.objects[0]->klass == CLASS_UNIVERSAL &&
107 o->list.objects[0]->tag == TAG_OID) {
108 name->oids[i] = r_asn1_stringify_oid (o->list.objects[0]->sector, o->list.objects[0]->length);
109 }
110 RASN1Object *obj1 = o->list.objects[1];
111 if (obj1 && obj1->klass == CLASS_UNIVERSAL) {
112 name->names[i] = r_asn1_stringify_string (obj1->sector, obj1->length);
113 }
114 }
115 }
116 }
117 }
118 return true;
119 }
120
r_x509_parse_extension(RX509Extension * ext,RASN1Object * object)121 bool r_x509_parse_extension (RX509Extension *ext, RASN1Object *object) {
122 RASN1Object *o;
123 if (!ext || !object || object->list.length < 2) {
124 return false;
125 }
126 o = object->list.objects[0];
127 if (o && o->tag == TAG_OID) {
128 ext->extnID = r_asn1_stringify_oid (o->sector, o->length);
129 o = object->list.objects[1];
130 if (o->tag == TAG_BOOLEAN && object->list.length > 2) {
131 //This field is optional (so len must be 3)
132 ext->critical = o->sector[0] != 0;
133 o = object->list.objects[2];
134 }
135 if (o->tag == TAG_OCTETSTRING) {
136 ext->extnValue = r_asn1_create_binary (o->sector, o->length);
137 }
138 }
139 return true;
140 }
141
r_x509_parse_extensions(RX509Extensions * ext,RASN1Object * object)142 bool r_x509_parse_extensions (RX509Extensions *ext, RASN1Object *object) {
143 ut32 i;
144 if (!ext || !object || object->list.length != 1 || !object->list.objects[0]->length) {
145 return false;
146 }
147 object = object->list.objects[0];
148 ext->extensions = (RX509Extension **)calloc (object->list.length, sizeof (RX509Extension *));
149 if (!ext->extensions) {
150 return false;
151 }
152 ext->length = object->list.length;
153 for (i = 0; i < object->list.length; i++) {
154 ext->extensions[i] = R_NEW0 (RX509Extension);
155 if (!r_x509_parse_extension (ext->extensions[i], object->list.objects[i])) {
156 r_x509_free_extension (ext->extensions[i]);
157 ext->extensions[i] = NULL;
158 }
159 }
160 return true;
161 }
162
r_x509_parse_tbscertificate(RX509TBSCertificate * tbsc,RASN1Object * object)163 bool r_x509_parse_tbscertificate (RX509TBSCertificate *tbsc, RASN1Object *object) {
164 RASN1Object **elems;
165 ut32 i;
166 ut32 shift = 0;
167 if (!tbsc || !object || object->list.length < 6) {
168 return false;
169 }
170 elems = object->list.objects;
171 //Following RFC
172 if (elems[0]->list.length == 1 &&
173 elems[0]->klass == CLASS_CONTEXT &&
174 elems[0]->form == FORM_CONSTRUCTED &&
175 elems[0]->list.objects[0]->tag == TAG_INTEGER &&
176 elems[0]->list.objects[0]->length == 1) {
177 //Integer inside a CLASS_CONTEXT
178 tbsc->version = (ut32)elems[0]->list.objects[0]->sector[0];
179 shift = 1;
180 } else {
181 tbsc->version = 0;
182 }
183 if (shift < object->list.length && elems[shift]->klass == CLASS_UNIVERSAL && elems[shift]->tag == TAG_INTEGER) {
184 tbsc->serialNumber = r_asn1_stringify_integer (elems[shift]->sector, elems[shift]->length);
185 }
186 r_x509_parse_algorithmidentifier (&tbsc->signature, elems[shift + 1]);
187 r_x509_parse_name (&tbsc->issuer, elems[shift + 2]);
188 r_x509_parse_validity (&tbsc->validity, elems[shift + 3]);
189 r_x509_parse_name (&tbsc->subject, elems[shift + 4]);
190 r_x509_parse_subjectpublickeyinfo (&tbsc->subjectPublicKeyInfo, elems[shift + 5]);
191 if (tbsc->version > 0) {
192 for (i = shift + 6; i < object->list.length; i++) {
193 if (!elems[i] || elems[i]->klass != CLASS_CONTEXT) {
194 continue;
195 }
196 if (elems[i]->tag == 1) {
197 tbsc->issuerUniqueID = r_asn1_create_binary (object->list.objects[i]->sector, object->list.objects[i]->length);
198 }
199 if (!elems[i]) {
200 continue;
201 }
202 if (elems[i]->tag == 2) {
203 tbsc->subjectUniqueID = r_asn1_create_binary (object->list.objects[i]->sector, object->list.objects[i]->length);
204 }
205 if (!elems[i]) {
206 continue;
207 }
208 if (tbsc->version == 2 && elems[i]->tag == 3 && elems[i]->form == FORM_CONSTRUCTED) {
209 r_x509_parse_extensions (&tbsc->extensions, elems[i]);
210 }
211 }
212 }
213 return true;
214 }
215
r_x509_parse_certificate(RASN1Object * object)216 RX509Certificate *r_x509_parse_certificate (RASN1Object *object) {
217 if (!object) {
218 return NULL;
219 }
220 RX509Certificate *cert = R_NEW0 (RX509Certificate);
221 if (!cert) {
222 goto fail;
223 }
224 if (object->klass != CLASS_UNIVERSAL || object->form != FORM_CONSTRUCTED || object->list.length != 3) {
225 R_FREE (cert);
226 goto fail;
227 }
228 RASN1Object *tmp = object->list.objects[2];
229 if (!tmp) {
230 R_FREE (cert);
231 goto fail;
232 }
233 if (tmp->klass != CLASS_UNIVERSAL || tmp->form != FORM_PRIMITIVE || tmp->tag != TAG_BITSTRING) {
234 R_FREE (cert);
235 goto fail;
236 }
237 cert->signature = r_asn1_create_binary (object->list.objects[2]->sector, object->list.objects[2]->length);
238 r_x509_parse_tbscertificate (&cert->tbsCertificate, object->list.objects[0]);
239
240 if (!r_x509_parse_algorithmidentifier (&cert->algorithmIdentifier, object->list.objects[1])) {
241 R_FREE (cert);
242 }
243 fail:
244 r_asn1_free_object (object);
245 return cert;
246 }
247
r_x509_parse_certificate2(const ut8 * buffer,ut32 length)248 RX509Certificate *r_x509_parse_certificate2 (const ut8 *buffer, ut32 length) {
249 RX509Certificate *certificate;
250 RASN1Object *object;
251 if (!buffer || !length) {
252 return NULL;
253 }
254 object = r_asn1_create_object (buffer, length, buffer);
255 certificate = r_x509_parse_certificate (object);
256 //object freed by r_x509_parse_certificate
257 return certificate;
258 }
259
r_x509_parse_crlentry(RASN1Object * object)260 RX509CRLEntry *r_x509_parse_crlentry (RASN1Object *object) {
261 RX509CRLEntry *entry;
262 if (!object || object->list.length != 2) {
263 return NULL;
264 }
265 entry = (RX509CRLEntry *)malloc (sizeof (RX509CRLEntry));
266 if (!entry) {
267 return NULL;
268 }
269 entry->userCertificate = r_asn1_create_binary (object->list.objects[0]->sector, object->list.objects[0]->length);
270 entry->revocationDate = r_asn1_stringify_utctime (object->list.objects[1]->sector, object->list.objects[1]->length);
271 return entry;
272 }
273
r_x509_parse_crl(RASN1Object * object)274 R_API RX509CertificateRevocationList *r_x509_parse_crl(RASN1Object *object) {
275 RX509CertificateRevocationList *crl;
276 RASN1Object **elems;
277 if (!object || object->list.length < 4) {
278 return NULL;
279 }
280 crl = (RX509CertificateRevocationList *)malloc (sizeof (RX509CertificateRevocationList));
281 if (!crl) {
282 return NULL;
283 }
284 memset (crl, 0, sizeof (RX509CertificateRevocationList));
285 elems = object->list.objects;
286 r_x509_parse_algorithmidentifier (&crl->signature, elems[0]);
287 r_x509_parse_name (&crl->issuer, elems[1]);
288 crl->lastUpdate = r_asn1_stringify_utctime (elems[2]->sector, elems[2]->length);
289 crl->nextUpdate = r_asn1_stringify_utctime (elems[3]->sector, elems[3]->length);
290 if (object->list.length > 4 && object->list.objects[4]) {
291 ut32 i;
292 crl->revokedCertificates = calloc (object->list.objects[4]->list.length, sizeof (RX509CRLEntry *));
293 if (!crl->revokedCertificates) {
294 free (crl);
295 return NULL;
296 }
297 crl->length = object->list.objects[4]->list.length;
298 for (i = 0; i < object->list.objects[4]->list.length; i++) {
299 crl->revokedCertificates[i] = r_x509_parse_crlentry (object->list.objects[4]->list.objects[i]);
300 }
301 }
302 return crl;
303 }
304
r_x509_free_algorithmidentifier(RX509AlgorithmIdentifier * ai)305 void r_x509_free_algorithmidentifier (RX509AlgorithmIdentifier *ai) {
306 if (ai) {
307 // no need to free ai, since this functions is used internally
308 r_asn1_free_string (ai->algorithm);
309 r_asn1_free_string (ai->parameters);
310 }
311 }
312
r_x509_free_validity(RX509Validity * validity)313 static void r_x509_free_validity(RX509Validity *validity) {
314 if (validity) {
315 // not freeing validity since it's not allocated dinamically
316 r_asn1_free_string (validity->notAfter);
317 r_asn1_free_string (validity->notBefore);
318 }
319 }
320
r_x509_free_name(RX509Name * name)321 void r_x509_free_name (RX509Name *name) {
322 ut32 i;
323 if (!name) {
324 return;
325 }
326 if (name->names) {
327 for (i = 0; i < name->length; i++) {
328 r_asn1_free_string (name->oids[i]);
329 r_asn1_free_string (name->names[i]);
330 }
331 R_FREE (name->names);
332 R_FREE (name->oids);
333 }
334 // not freeing name since it's not allocated dinamically
335 }
336
r_x509_free_extension(RX509Extension * ex)337 void r_x509_free_extension (RX509Extension *ex) {
338 if (ex) {
339 r_asn1_free_string (ex->extnID);
340 r_asn1_free_binary (ex->extnValue);
341 //this is allocated dinamically so, i'll free
342 free (ex);
343 }
344 }
345
r_x509_free_extensions(RX509Extensions * ex)346 void r_x509_free_extensions (RX509Extensions *ex) {
347 ut32 i;
348 if (!ex) {
349 return;
350 }
351 if (ex->extensions) {
352 for (i = 0; i < ex->length; i++) {
353 r_x509_free_extension (ex->extensions[i]);
354 }
355 free (ex->extensions);
356 }
357 //no need to free ex, since this functions is used internally
358 }
359
r_x509_free_subjectpublickeyinfo(RX509SubjectPublicKeyInfo * spki)360 void r_x509_free_subjectpublickeyinfo (RX509SubjectPublicKeyInfo *spki) {
361 if (spki) {
362 r_x509_free_algorithmidentifier (&spki->algorithm);
363 r_asn1_free_binary (spki->subjectPublicKey);
364 r_asn1_free_binary (spki->subjectPublicKeyExponent);
365 r_asn1_free_binary (spki->subjectPublicKeyModule);
366 // No need to free spki, since it's a static variable.
367 }
368 }
369
r_x509_free_tbscertificate(RX509TBSCertificate * tbsc)370 void r_x509_free_tbscertificate (RX509TBSCertificate *tbsc) {
371 if (tbsc) {
372 // version is ut32
373 r_asn1_free_string (tbsc->serialNumber);
374 r_x509_free_algorithmidentifier (&tbsc->signature);
375 r_x509_free_name (&tbsc->issuer);
376 r_x509_free_validity (&tbsc->validity);
377 r_x509_free_name (&tbsc->subject);
378 r_x509_free_subjectpublickeyinfo (&tbsc->subjectPublicKeyInfo);
379 r_asn1_free_binary (tbsc->subjectUniqueID);
380 r_asn1_free_binary (tbsc->issuerUniqueID);
381 r_x509_free_extensions (&tbsc->extensions);
382 //no need to free tbsc, since this functions is used internally
383 }
384 }
385
r_x509_free_certificate(RX509Certificate * certificate)386 void r_x509_free_certificate (RX509Certificate *certificate) {
387 if (certificate) {
388 r_asn1_free_binary (certificate->signature);
389 r_x509_free_algorithmidentifier (&certificate->algorithmIdentifier);
390 r_x509_free_tbscertificate (&certificate->tbsCertificate);
391 free (certificate);
392 }
393 }
394
r_x509_free_crlentry(RX509CRLEntry * entry)395 static void r_x509_free_crlentry(RX509CRLEntry *entry) {
396 if (entry) {
397 r_asn1_free_binary (entry->userCertificate);
398 r_asn1_free_string (entry->revocationDate);
399 free (entry);
400 }
401 }
402
r_x509_free_crl(RX509CertificateRevocationList * crl)403 void r_x509_free_crl (RX509CertificateRevocationList *crl) {
404 ut32 i;
405 if (crl) {
406 r_x509_free_algorithmidentifier (&crl->signature);
407 r_x509_free_name (&crl->issuer);
408 r_asn1_free_string (crl->nextUpdate);
409 r_asn1_free_string (crl->lastUpdate);
410 if (crl->revokedCertificates) {
411 for (i = 0; i < crl->length; i++) {
412 r_x509_free_crlentry (crl->revokedCertificates[i]);
413 crl->revokedCertificates[i] = NULL;
414 }
415 R_FREE (crl->revokedCertificates);
416 }
417 free (crl);
418 }
419 }
420
r_x509_validity_dump(RX509Validity * validity,const char * pad,RStrBuf * sb)421 static void r_x509_validity_dump(RX509Validity *validity, const char *pad, RStrBuf *sb) {
422 if (!validity) {
423 return;
424 }
425 if (!pad) {
426 pad = "";
427 }
428 const char *b = validity->notBefore ? validity->notBefore->string : "Missing";
429 const char *a = validity->notAfter ? validity->notAfter->string : "Missing";
430 r_strbuf_appendf (sb, "%sNot Before: %s\n%sNot After: %s\n", pad, b, pad, a);
431 }
432
r_x509_name_dump(RX509Name * name,const char * pad,RStrBuf * sb)433 void r_x509_name_dump (RX509Name *name, const char *pad, RStrBuf *sb) {
434 ut32 i;
435 if (!name) {
436 return;
437 }
438 if (!pad) {
439 pad = "";
440 }
441 for (i = 0; i < name->length; i++) {
442 if (!name->oids[i] || !name->names[i]) {
443 continue;
444 }
445 r_strbuf_appendf (sb, "%s%s: %s\n", pad, name->oids[i]->string, name->names[i]->string);
446 }
447 }
448
r_x509_subjectpublickeyinfo_dump(RX509SubjectPublicKeyInfo * spki,const char * pad,RStrBuf * sb)449 static void r_x509_subjectpublickeyinfo_dump(RX509SubjectPublicKeyInfo *spki, const char *pad, RStrBuf *sb) {
450 const char *a;
451 if (!spki) {
452 return;
453 }
454 if (!pad) {
455 pad = "";
456 }
457 a = spki->algorithm.algorithm ? spki->algorithm.algorithm->string : "Missing";
458 RASN1String *m = NULL;
459 if (spki->subjectPublicKeyModule) {
460 m = r_asn1_stringify_integer (spki->subjectPublicKeyModule->binary, spki->subjectPublicKeyModule->length);
461 }
462 // RASN1String* e = r_asn1_stringify_bytes (spki->subjectPublicKeyExponent->sector, spki->subjectPublicKeyExponent->length);
463 // r = snprintf (buffer, length, "%sAlgorithm: %s\n%sModule: %s\n%sExponent: %u bytes\n%s\n", pad, a, pad, m->string,
464 // pad, spki->subjectPublicKeyExponent->length - 1, e->string);
465 r_strbuf_appendf (sb, "%sAlgorithm: %s\n%sModule: %s\n%sExponent: %u bytes\n", pad, a, pad, m ? m->string : "Missing",
466 pad, spki->subjectPublicKeyExponent ? spki->subjectPublicKeyExponent->length - 1 : 0);
467 r_asn1_free_string (m);
468 // r_asn1_free_string (e);
469 }
470
r_x509_extensions_dump(RX509Extensions * exts,const char * pad,RStrBuf * sb)471 static void r_x509_extensions_dump(RX509Extensions *exts, const char *pad, RStrBuf *sb) {
472 ut32 i;
473 if (!exts) {
474 return;
475 }
476 if (!pad) {
477 pad = "";
478 }
479 for (i = 0; i < exts->length; i++) {
480 RX509Extension *e = exts->extensions[i];
481 if (!e) {
482 continue;
483 }
484 //TODO handle extensions..
485 //s = r_asn1_stringify_bytes (e->extnValue->sector, e->extnValue->length);
486 r_strbuf_appendf (sb, "%s%s: %s\n%s%u bytes\n", pad,
487 e->extnID ? e->extnID->string : "Missing",
488 e->critical ? "critical" : "",
489 pad, e->extnValue ? e->extnValue->length : 0);
490 //r_asn1_free_string (s);
491 }
492 }
493
r_x509_tbscertificate_dump(RX509TBSCertificate * tbsc,const char * pad,RStrBuf * sb)494 static void r_x509_tbscertificate_dump(RX509TBSCertificate *tbsc, const char *pad, RStrBuf *sb) {
495 RASN1String *sid = NULL, *iid = NULL;
496 if (!tbsc) {
497 return;
498 }
499 if (!pad) {
500 pad = "";
501 }
502 char *pad2 = r_str_newf ("%s ", pad);
503 if (!pad2) {
504 return;
505 }
506 r_strbuf_appendf (sb, "%sVersion: v%u\n"
507 "%sSerial Number:\n%s %s\n"
508 "%sSignature Algorithm:\n%s %s\n"
509 "%sIssuer:\n",
510 pad, tbsc->version + 1,
511 pad, pad, tbsc->serialNumber ? tbsc->serialNumber->string : "Missing",
512 pad, pad, tbsc->signature.algorithm ? tbsc->signature.algorithm->string : "Missing",
513 pad);
514 r_x509_name_dump (&tbsc->issuer, pad2, sb);
515
516 r_strbuf_appendf (sb, "%sValidity:\n", pad);
517 r_x509_validity_dump (&tbsc->validity, pad2, sb);
518
519 r_strbuf_appendf (sb, "%sSubject:\n", pad);
520 r_x509_name_dump (&tbsc->subject, pad2, sb);
521
522 r_strbuf_appendf (sb, "%sSubject Public Key Info:\n", pad);
523 r_x509_subjectpublickeyinfo_dump (&tbsc->subjectPublicKeyInfo, pad2, sb);
524
525 if (tbsc->issuerUniqueID) {
526 iid = r_asn1_stringify_integer (tbsc->issuerUniqueID->binary, tbsc->issuerUniqueID->length);
527 if (iid) {
528 r_strbuf_appendf (sb, "%sIssuer Unique ID:\n%s %s", pad, pad, iid->string);
529 r_asn1_free_string (iid);
530 }
531 }
532 if (tbsc->subjectUniqueID) {
533 sid = r_asn1_stringify_integer (tbsc->subjectUniqueID->binary, tbsc->subjectUniqueID->length);
534 if (sid) {
535 r_strbuf_appendf (sb, "%sSubject Unique ID:\n%s %s", pad, pad, sid->string);
536 r_asn1_free_string (sid);
537 }
538 }
539
540 r_strbuf_appendf (sb, "%sExtensions:\n", pad);
541 r_x509_extensions_dump (&tbsc->extensions, pad2, sb);
542 free (pad2);
543 }
544
r_x509_certificate_dump(RX509Certificate * cert,const char * pad,RStrBuf * sb)545 void r_x509_certificate_dump (RX509Certificate *cert, const char *pad, RStrBuf *sb) {
546 RASN1String *algo = NULL;
547 char *pad2;
548 if (!cert) {
549 return;
550 }
551 if (!pad) {
552 pad = "";
553 }
554 pad2 = r_str_newf ("%s ", pad);
555 if (!pad2) {
556 return;
557 }
558 r_strbuf_appendf (sb, "%sTBSCertificate:\n", pad);
559 r_x509_tbscertificate_dump (&cert->tbsCertificate, pad2, sb);
560
561 algo = cert->algorithmIdentifier.algorithm;
562 // signature = r_asn1_stringify_bytes (certificate->signature->binary, certificate->signature->length);
563 // eprintf ("%sAlgorithm:\n%s%s\n%sSignature: %u bytes\n%s\n",
564 // pad, pad2, algo ? algo->string : "",
565 // pad, certificate->signature->length, signature ? signature->string : "");
566 r_strbuf_appendf (sb, "%sAlgorithm:\n%s%s\n%sSignature: %u bytes\n",
567 pad, pad2, algo ? algo->string : "", pad, cert->signature->length);
568 free (pad2);
569 // r_asn1_free_string (signature);
570 }
571
r_x509_crlentry_dump(RX509CRLEntry * crle,const char * pad,RStrBuf * sb)572 void r_x509_crlentry_dump (RX509CRLEntry *crle, const char *pad, RStrBuf *sb) {
573 RASN1String *id = NULL, *utc = NULL;
574 if (!crle) {
575 return;
576 }
577 if (!pad) {
578 pad = "";
579 }
580 utc = crle->revocationDate;
581 if (crle->userCertificate) {
582 id = r_asn1_stringify_integer (crle->userCertificate->binary, crle->userCertificate->length);
583 }
584 r_strbuf_appendf (sb, "%sUser Certificate:\n%s %s\n"
585 "%sRevocation Date:\n%s %s\n",
586 pad, pad, id ? id->string : "Missing",
587 pad, pad, utc ? utc->string : "Missing");
588 r_asn1_free_string (id);
589 }
590
r_x509_crl_to_string(RX509CertificateRevocationList * crl,const char * pad)591 R_API char *r_x509_crl_to_string(RX509CertificateRevocationList *crl, const char *pad) {
592 RASN1String *algo = NULL, *last = NULL, *next = NULL;
593 ut32 i;
594 char *pad2, *pad3;
595 if (!crl) {
596 return NULL;
597 }
598 if (!pad) {
599 pad = "";
600 }
601 pad3 = r_str_newf ("%s ", pad);
602 if (!pad3) {
603 return NULL;
604 }
605 pad2 = pad3 + 2;
606 algo = crl->signature.algorithm;
607 last = crl->lastUpdate;
608 next = crl->nextUpdate;
609 RStrBuf *sb = r_strbuf_new ("");
610 r_strbuf_appendf (sb, "%sCRL:\n%sSignature:\n%s%s\n%sIssuer\n", pad, pad2, pad3,
611 algo ? algo->string : "", pad2);
612 r_x509_name_dump (&crl->issuer, pad3, sb);
613
614 r_strbuf_appendf (sb, "%sLast Update: %s\n%sNext Update: %s\n%sRevoked Certificates:\n",
615 pad2, last ? last->string : "Missing",
616 pad2, next ? next->string : "Missing", pad2);
617
618 for (i = 0; i < crl->length; i++) {
619 r_x509_crlentry_dump (crl->revokedCertificates[i], pad3, sb);
620 }
621
622 free (pad3);
623 return r_strbuf_drain (sb);
624 }
625
r_x509_validity_json(PJ * pj,RX509Validity * validity)626 R_API void r_x509_validity_json(PJ *pj, RX509Validity *validity) {
627 if (validity) {
628 if (validity->notBefore) {
629 pj_ks (pj, "NotBefore", validity->notBefore->string);
630 }
631 if (validity->notAfter) {
632 pj_ks (pj, "NotAfter", validity->notAfter->string);
633 }
634 }
635 }
636
r_x509_name_json(PJ * pj,RX509Name * name)637 R_API void r_x509_name_json(PJ *pj, RX509Name *name) {
638 ut32 i;
639 for (i = 0; i < name->length; i++) {
640 if (!name->oids[i] || !name->names[i]) {
641 continue;
642 }
643 pj_ks (pj, name->oids[i]->string, name->names[i]->string);
644 }
645 }
646
r_x509_subjectpublickeyinfo_json(PJ * pj,RX509SubjectPublicKeyInfo * spki)647 R_API void r_x509_subjectpublickeyinfo_json(PJ *pj, RX509SubjectPublicKeyInfo *spki) {
648 RASN1String *m = NULL;
649 if (spki) {
650 if (spki->algorithm.algorithm) {
651 pj_ks (pj, "Algorithm", spki->algorithm.algorithm->string);
652 }
653 if (spki->subjectPublicKeyModule) {
654 m = r_asn1_stringify_integer (spki->subjectPublicKeyModule->binary, spki->subjectPublicKeyModule->length);
655 if (m) {
656 pj_ks (pj, "Module", m->string);
657 }
658 r_asn1_free_string (m);
659 }
660 if (spki->subjectPublicKeyExponent) {
661 m = r_asn1_stringify_integer (spki->subjectPublicKeyExponent->binary, spki->subjectPublicKeyExponent->length);
662 if (m) {
663 pj_ks (pj, "Exponent", m->string);
664 }
665 r_asn1_free_string (m);
666 }
667 }
668 }
669
r_x509_extensions_json(PJ * pj,RX509Extensions * exts)670 R_API void r_x509_extensions_json(PJ *pj, RX509Extensions *exts) {
671 if (exts) {
672 RASN1String *m = NULL;
673 ut32 i;
674 pj_a (pj);
675 for (i = 0; i < exts->length; i++) {
676 RX509Extension *e = exts->extensions[i];
677 if (!e) {
678 continue;
679 }
680 pj_o (pj);
681 if (e->extnID) {
682 pj_ks (pj, "OID", e->extnID->string);
683 }
684 if (e->critical) {
685 pj_kb (pj, "Critical", e->critical);
686 }
687 //TODO handle extensions correctly..
688 if (e->extnValue) {
689 m = r_asn1_stringify_integer (e->extnValue->binary, e->extnValue->length);
690 if (m) {
691 pj_ks (pj, "Value", m->string);
692 }
693 r_asn1_free_string (m);
694 }
695 pj_end (pj);
696 }
697 pj_end (pj);
698 pj_end (pj);
699 }
700 }
701
r_x509_crlentry_json(PJ * pj,RX509CRLEntry * crle)702 R_API void r_x509_crlentry_json(PJ *pj, RX509CRLEntry *crle) {
703 RASN1String *m = NULL;
704 if (crle) {
705 if (crle->userCertificate) {
706 m = r_asn1_stringify_integer (crle->userCertificate->binary, crle->userCertificate->length);
707 if (m) {
708 pj_ks (pj, "UserCertificate", m->string);
709 }
710 r_asn1_free_string (m);
711 }
712 if (crle->revocationDate) {
713 pj_ks (pj, "RevocationDate", crle->revocationDate->string);
714 }
715 }
716 }
717
r_x509_crl_json(PJ * pj,RX509CertificateRevocationList * crl)718 R_API void r_x509_crl_json(PJ *pj, RX509CertificateRevocationList *crl) {
719 ut32 i;
720 if (crl) {
721 if (crl->signature.algorithm) {
722 pj_ks (pj, "Signature", crl->signature.algorithm->string);
723 }
724 pj_k (pj, "Issuer");
725 pj_o (pj);
726 r_x509_name_json (pj, &crl->issuer);
727 pj_end (pj);
728 if (crl->lastUpdate) {
729 pj_ks (pj, "LastUpdate", crl->lastUpdate->string);
730 }
731 if (crl->nextUpdate) {
732 pj_ks (pj, "NextUpdate", crl->nextUpdate->string);
733 }
734 pj_k (pj, "RevokedCertificates");
735 pj_a (pj);
736 for (i = 0; i < crl->length; i++) {
737 r_x509_crlentry_json (pj, crl->revokedCertificates[i]);
738 }
739 pj_end (pj);
740 }
741 }
742
r_x509_tbscertificate_json(PJ * pj,RX509TBSCertificate * tbsc)743 R_API void r_x509_tbscertificate_json(PJ *pj, RX509TBSCertificate *tbsc) {
744 pj_o (pj);
745 RASN1String *m = NULL;
746 if (tbsc) {
747 pj_ki (pj, "Version", tbsc->version + 1);
748 if (tbsc->serialNumber) {
749 pj_ks (pj, "SerialNumber", tbsc->serialNumber->string);
750 }
751 if (tbsc->signature.algorithm) {
752 pj_ks (pj, "SignatureAlgorithm", tbsc->signature.algorithm->string);
753 }
754 pj_k (pj, "Issuer");
755 pj_o (pj);
756 r_x509_name_json (pj, &tbsc->issuer);
757 pj_end (pj);
758 pj_k (pj, "Validity");
759 pj_o (pj);
760 r_x509_validity_json (pj, &tbsc->validity);
761 pj_end (pj);
762 pj_k (pj, "Subject");
763 pj_o (pj);
764 r_x509_name_json (pj, &tbsc->subject);
765 pj_end (pj);
766 pj_k (pj, "SubjectPublicKeyInfo");
767 pj_o (pj);
768 r_x509_subjectpublickeyinfo_json (pj, &tbsc->subjectPublicKeyInfo);
769 pj_end (pj);
770 if (tbsc->issuerUniqueID) {
771 m = r_asn1_stringify_integer (tbsc->issuerUniqueID->binary, tbsc->issuerUniqueID->length);
772 if (m) {
773 pj_ks (pj, "IssuerUniqueID", m->string);
774 }
775 r_asn1_free_string (m);
776 }
777 if (tbsc->subjectUniqueID) {
778 m = r_asn1_stringify_integer (tbsc->subjectUniqueID->binary, tbsc->subjectUniqueID->length);
779 if (m) {
780 pj_ks (pj, "SubjectUniqueID", m->string);
781 }
782 r_asn1_free_string (m);
783 }
784 pj_k (pj, "Extensions");
785 r_x509_extensions_json (pj, &tbsc->extensions);
786 }
787 }
788
r_x509_certificate_json(PJ * pj,RX509Certificate * certificate)789 R_API void r_x509_certificate_json(PJ *pj, RX509Certificate *certificate) {
790 if (!certificate) {
791 return;
792 }
793 RASN1String *m = NULL;
794 pj_o (pj);
795 pj_k (pj, "TBSCertificate");
796 r_x509_tbscertificate_json (pj, &certificate->tbsCertificate);
797 if (certificate->algorithmIdentifier.algorithm) {
798 pj_ks (pj, "Algorithm", certificate->algorithmIdentifier.algorithm->string);
799 }
800 if (certificate->signature) {
801 m = r_asn1_stringify_integer (certificate->signature->binary, certificate->signature->length);
802 if (m) {
803 pj_ks (pj, "Signature", m->string);
804 }
805 r_asn1_free_string (m);
806 }
807 pj_end (pj);
808 }
809