forked from estkme-group/lpac
-
Notifications
You must be signed in to change notification settings - Fork 0
/
es10a.c
138 lines (116 loc) · 3.47 KB
/
es10a.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "euicc.private.h"
#include "es10a.h"
#include "hexutil.h"
#include "derutil.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int es10a_get_euicc_configured_addresses(struct euicc_ctx *ctx, struct es10a_euicc_configured_addresses *address)
{
int fret = 0;
struct euicc_derutil_node n_request = {
.tag = 0xBF3C, // EuiccConfiguredAddressesRequest
};
uint32_t reqlen;
uint8_t *respbuf = NULL;
unsigned resplen;
struct euicc_derutil_node tmpnode, n_Response;
memset(address, 0, sizeof(*address));
reqlen = sizeof(ctx->apdu._internal.request_buffer.body);
if (euicc_derutil_pack(ctx->apdu._internal.request_buffer.body, &reqlen, &n_request))
{
goto err;
}
if (es10x_command(ctx, &respbuf, &resplen, ctx->apdu._internal.request_buffer.body, reqlen) < 0)
{
goto err;
}
if (euicc_derutil_unpack_find_tag(&n_Response, n_request.tag, respbuf, resplen))
{
goto err;
}
if (euicc_derutil_unpack_find_tag(&tmpnode, 0x80, n_Response.value, n_Response.length) == 0)
{
address->defaultDpAddress = malloc(tmpnode.length + 1);
if (address->defaultDpAddress)
{
memcpy(address->defaultDpAddress, tmpnode.value, tmpnode.length);
address->defaultDpAddress[tmpnode.length] = '\0';
}
}
if (euicc_derutil_unpack_find_tag(&tmpnode, 0x81, n_Response.value, n_Response.length) == 0)
{
address->rootDsAddress = malloc(tmpnode.length + 1);
if (address->rootDsAddress)
{
memcpy(address->rootDsAddress, tmpnode.value, tmpnode.length);
address->rootDsAddress[tmpnode.length] = '\0';
}
}
goto exit;
err:
fret = -1;
free(address->defaultDpAddress);
address->defaultDpAddress = NULL;
free(address->rootDsAddress);
address->rootDsAddress = NULL;
exit:
free(respbuf);
respbuf = NULL;
return fret;
}
int es10a_set_default_dp_address(struct euicc_ctx *ctx, const char *smdp)
{
int fret = 0;
struct euicc_derutil_node n_request = {
.tag = 0xBF3F, // SetDefaultDpAddressRequest
.pack = {
.child = &(struct euicc_derutil_node){
.tag = 0x80,
.length = strlen(smdp),
.value = (const uint8_t *)smdp,
},
},
};
uint32_t reqlen;
uint8_t *respbuf = NULL;
unsigned resplen;
struct euicc_derutil_node tmpnode;
reqlen = sizeof(ctx->apdu._internal.request_buffer.body);
if (euicc_derutil_pack(ctx->apdu._internal.request_buffer.body, &reqlen, &n_request))
{
goto err;
}
if (es10x_command(ctx, &respbuf, &resplen, ctx->apdu._internal.request_buffer.body, reqlen) < 0)
{
goto err;
}
if (euicc_derutil_unpack_find_tag(&tmpnode, n_request.tag, respbuf, resplen) < 0)
{
goto err;
}
if (euicc_derutil_unpack_find_tag(&tmpnode, 0x80, tmpnode.value, tmpnode.length) < 0)
{
goto err;
}
fret = euicc_derutil_convert_bin2long(tmpnode.value, tmpnode.length);
goto exit;
err:
fret = -1;
exit:
free(respbuf);
respbuf = NULL;
return fret;
}
void es10a_euicc_configured_addresses_free(struct es10a_euicc_configured_addresses *address)
{
if (!address)
{
return;
}
free(address->defaultDpAddress);
free(address->rootDsAddress);
memset(address, 0x00, sizeof(struct es10a_euicc_configured_addresses));
}