fix little endian vs big endian in the macros... again... but this time correct
[RRG-proxmark3.git] / client / src / crypto / asn1utils.c
blob1d89009e97ed78e7b0bae91beed94a5714a4f8b0
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2018 Merlok
3 //
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
6 // the license.
7 //-----------------------------------------------------------------------------
8 // asn.1 utils
9 //-----------------------------------------------------------------------------
11 #include "asn1utils.h"
12 #include <ctype.h>
13 #include <stdlib.h>
14 #include <mbedtls/asn1.h>
15 #include "ui.h" // Print...
16 #include "emv/tlv.h"
17 #include "asn1dump.h"
18 #include "util.h"
20 int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *rval, uint8_t *sval) {
21 if (!signature || !signaturelen || !rval || !sval)
22 return PM3_EINVARG;
24 int res = PM3_SUCCESS;
25 unsigned char *p = signature;
26 const unsigned char *end = p + signaturelen;
27 size_t len;
28 mbedtls_mpi xmpi;
30 if ((res = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) == 0) {
31 mbedtls_mpi_init(&xmpi);
32 res = mbedtls_asn1_get_mpi(&p, end, &xmpi);
33 if (res) {
34 mbedtls_mpi_free(&xmpi);
35 goto exit;
38 res = mbedtls_mpi_write_binary(&xmpi, rval, 32);
39 mbedtls_mpi_free(&xmpi);
40 if (res)
41 goto exit;
43 mbedtls_mpi_init(&xmpi);
44 res = mbedtls_asn1_get_mpi(&p, end, &xmpi);
45 if (res) {
46 mbedtls_mpi_free(&xmpi);
47 goto exit;
50 res = mbedtls_mpi_write_binary(&xmpi, sval, 32);
51 mbedtls_mpi_free(&xmpi);
52 if (res)
53 goto exit;
55 // check size
56 if (end != p)
57 return PM3_ESOFT;
60 exit:
61 return res;
64 static void asn1_print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) {
65 bool candump = true;
66 asn1_tag_dump(tlv, level, &candump);
67 if (is_leaf && candump) {
68 print_buffer(tlv->value, tlv->len, level + 1);
72 int asn1_print(uint8_t *asn1buf, size_t asn1buflen, const char *indent) {
74 struct tlvdb *t = tlvdb_parse_multi(asn1buf, asn1buflen);
75 if (t) {
76 tlvdb_visit(t, asn1_print_cb, NULL, 0);
77 tlvdb_free(t);
78 } else {
79 PrintAndLogEx(ERR, "Can't parse data as TLV tree");
80 return PM3_ESOFT;
83 return PM3_SUCCESS;