Skip to content

Commit 438e62e

Browse files
authored
Merge pull request #1 from wllm-rbnt/improvements
Env var support + multi root unwrap merge
2 parents 5826b9d + 59f48a0 commit 438e62e

File tree

6 files changed

+118
-118
lines changed

6 files changed

+118
-118
lines changed

EXAMPLES.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@
44

55
Take an arbitrary DER encoded certificate:
66

7-
```bash
7+
```console
88
$ wget -o /dev/null https://pki.goog/repo/certs/gtsr1.der
99
```
1010

1111
Convert it to an ASN1_generate_nconf(3) compatible textual description:
1212

13-
```bash
13+
```console
1414
$ ./asn1template.pl gtsr1.der > gtsr1.tpl
1515
```
1616

1717
Convert it back to DER encoded ASN.1 with ASN1_generate_nconf(3):
1818

19-
```bash
19+
```console
2020
$ openssl asn1parse -genconf gtsr1.tpl -noout -out gtsr1_new.der
2121
```
2222

2323
Original and recreated DER files are identical:
24-
```bash
24+
```console
2525
$ diff gtsr1.der gtsr1_new.der
2626
$ echo $?
2727
0
@@ -34,17 +34,17 @@ https://github.com/drago-96/CVE-2022-0778 and this particular PR
3434
https://github.com/drago-96/CVE-2022-0778/pull/4 .
3535

3636
Following the details presented in https://github.com/drago-96/CVE-2022-0778/pull/4 , first, generate a new EC private key:
37-
```bash
37+
```console
3838
$ openssl ecparam -out ec.key -name prime256v1 -genkey -noout -param_enc explicit -conv_form compressed
3939
```
4040

4141
Then use it to generate a self signed certificate:
42-
```bash
42+
```console
4343
$ openssl req -new -x509 -key ec.key -out cert.der -outform DER -days 360 -subj "/CN=TEST/"
4444
```
4545

4646
We can then generate a template from this certificate:
47-
```bash
47+
```console
4848
$ ./asn1template.pl cert.der > cert.tpl
4949
$ cat cert.tpl
5050
asn1 = SEQUENCE:seq1@0-4-583
@@ -123,7 +123,7 @@ field51@503-2-8 = OBJECT:ecdsa-with-SHA256
123123
```
124124

125125
Change some of the values in the template according to https://github.com/drago-96/CVE-2022-0778 and https://github.com/drago-96/CVE-2022-0778/pull/4 :
126-
```bash
126+
```console
127127
$ diff -u cert.tpl cert_new.tpl
128128
--- cert.tpl 2022-08-18 15:42:00.593000000 +0200
129129
+++ cert_new.tpl 2022-08-18 15:44:01.220000000 +0200
@@ -146,13 +146,13 @@ $ diff -u cert.tpl cert_new.tpl
146146
```
147147

148148
Then convert the template back to DER encoded ASN.1:
149-
```bash
149+
```console
150150
$ openssl asn1parse -genconf cert_new.tpl -noout -out cert_new.der
151151

152152
```
153153

154154
Finally, try to display this certificate with a CVE-2022-0778 vulnerable OpenSSL installation:
155-
```bash
155+
```console
156156
$ openssl x509 -inform DER -in cert_new.der -noout -text
157157
```
158158

@@ -161,7 +161,7 @@ $ openssl x509 -inform DER -in cert_new.der -noout -text
161161
It works on certificates, but, more generally, on arbitrary DER encoded ASN.1
162162
blobs. Here is the same as example #1 but with a CRL file:
163163

164-
```bash
164+
```console
165165
$ wget -o /dev/null https://crl.pki.goog/gtsr1/gtsr1.crl
166166
$ ./asn1template.pl gtsr1.crl > gtsr1.tpl
167167
$ openssl asn1parse -genconf gtsr1.tpl -noout -out gtsr1_new.crl
@@ -172,7 +172,7 @@ $ echo $?
172172

173173
Or with an smime.p7s email signature taken from https://datatracker.ietf.org/doc/html/rfc4134 (page 87):
174174

175-
```bash
175+
```console
176176
$ cat <<EOF > smime.p7s.base64
177177
MIIDdwYJKoZIhvcNAQcCoIIDaDCCA2QCAQExCTAHBgUrDgMCGjALBgkqhkiG9w0BBwGgggL
178178
gMIIC3DCCApugAwIBAgICAMgwCQYHKoZIzjgEAzASMRAwDgYDVQQDEwdDYXJsRFNTMB4XDT
@@ -204,29 +204,29 @@ $ echo $?
204204

205205
It also works with PEM files:
206206

207-
```bash
207+
```console
208208
$ wget -o /dev/null https://pki.goog/repo/certs/gtsr1.pem
209209
```
210210

211211
Convert it to an ASN1_generate_nconf(3) compatible textual description:
212212

213-
```bash
213+
```console
214214
$ ./asn1template.pl --pem gtsr1.pem > gtsr1.tpl
215215
```
216216

217217
Convert it back to DER encoded ASN.1 with ASN1_generate_nconf(3):
218218

219-
```bash
219+
```console
220220
$ openssl asn1parse -genconf gtsr1.tpl -noout -out gtsr1_new.der
221221
```
222222

223223
Then back to PEM:
224-
```bash
224+
```console
225225
$ openssl x509 -inform DER -in gtsr1_new.der -outform PEM -out gtsr1_new.pem
226226
```
227227

228228
Original and recreated PEM files are identical:
229-
```bash
229+
```console
230230
$ diff gtsr1.pem gtsr1_new.pem
231231
$ echo $?
232232
0
@@ -236,23 +236,23 @@ $ echo $?
236236
Let's consider the following configuration template that contains an explicit
237237
tag definition:
238238

239-
```bash
239+
```console
240240
$ cat test.tpl
241241
asn1 = SEQUENCE:seq1
242242
[seq1]
243243
field1 = EXPLICIT:0A,IA5STRING:Hello World
244244
```
245245

246246
We can generate the corresponding DER encoded file:
247-
```bash
247+
```console
248248
$ openssl asn1parse -genconf test.tpl -out test.der
249249
0:d=0 hl=2 l= 15 cons: SEQUENCE
250250
2:d=1 hl=2 l= 13 cons: appl [ 0 ]
251251
4:d=2 hl=2 l= 11 prim: IA5STRING :Hello World
252252
```
253253

254254
The DER encoded file can be read with the asn1parse OpenSSL app:
255-
```bash
255+
```console
256256
$ openssl asn1parse -in test.der -i -inform D
257257
0:d=0 hl=2 l= 15 cons: SEQUENCE
258258
2:d=1 hl=2 l= 13 cons: appl [ 0 ]
@@ -263,7 +263,7 @@ We can see the entry point sequence (seq1) followed by a tagged sequence (appl
263263
[ 0 ]) containing the IA5STRING.
264264

265265
The template can then be extracted from the DER encoded file:
266-
```bash
266+
```console
267267
$ ./asn1template.pl test.der | tee test2.tpl
268268
asn1 = SEQUENCE:seq1@0-2-15
269269
[seq1@0-2-15]
@@ -274,7 +274,7 @@ field3@4-2-11 = IA5STRING:"Hello\ World"
274274
We can see that the explicit tag has been replaced by an implicitly tagged sequence (seq2).
275275

276276
This template can finally be used to generate the associated DER encode file:
277-
```bash
277+
```console
278278
$ openssl asn1parse -genconf test2.tpl -out test2.der
279279
0:d=0 hl=2 l= 15 cons: SEQUENCE
280280
2:d=1 hl=2 l= 13 cons: appl [ 0 ]
@@ -284,7 +284,7 @@ $ openssl asn1parse -genconf test2.tpl -out test2.der
284284
Both DER encoded files are identical. ```test.der``` originates from a
285285
configuration template with an explicit tag, ```test2.der``` originates from an
286286
equivalent configuration template containing an implicit tag:
287-
```bash
287+
```console
288288
$ diff test.der test2.der
289289
$ echo $?
290290
0

README.md

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ textual description that can be edited and later be fed to OpenSSL's
88
encoded ASN.1 structure.
99
The code is written in Perl with minimal dependencies. No compilation required.
1010

11-
```
11+
```console
1212
$ git clone https://github.com/wllm-rbnt/asn1template.git
1313
$ cd asn1template
1414
$ ./asn1template.pl -h
@@ -19,14 +19,17 @@ Default input file format is DER, use --pem (or -p) option to switch to PEM
1919
Use --multi-root (or -m) option to process multiple concatenated structures from a single input file
2020
Use --simple-labels (or -s) option to use simple numeric labels
2121
Use --help (or -h) to print this help message
22+
23+
Remove/Unwrap top-level SEQUENCE, use --pem (or -p) option to switch to PEM
24+
./asn1template.pl [--pem|-p] [--unwrap|-u] <encoded_file>
2225
```
2326

2427
Here is an example of usage. First, let's convert a PEM encoded certificate to
2528
a textual representation supported by ```ASN1_generate_nconf(3)```. The
2629
certificate we use in this example is a root CA certificate from Amazon. On
2730
Debian, it belongs to the ```ca-certificates``` package.
2831

29-
```
32+
```console
3033
$ ./asn1template.pl --pem /etc/ssl/certs/Amazon_Root_CA_3.pem | tee Amazon_Root_CA_3.tpl
3134
asn1 = SEQUENCE:seq1@0-4-438
3235
[seq1@0-4-438]
@@ -125,13 +128,13 @@ convert this template back to its original form using
125128
```ASN1_generate_nconf(3)```. This is done in 2 steps, first convert it to a
126129
DER encoded file, then convert this DER file to PEM format:
127130

128-
```
131+
```console
129132
$ openssl asn1parse -genconf Amazon_Root_CA_3.tpl -out Amazon_Root_CA_3_new.der
130133
$ openssl x509 -in Amazon_Root_CA_3_new.der -out Amazon_Root_CA_3_new.pem -outform PEM
131134
```
132135

133136
We can see that the original file and the one we regenerated are identical:
134-
```
137+
```console
135138
$ diff -u /etc/ssl/certs/Amazon_Root_CA_3.pem Amazon_Root_CA_3_new.pem
136139
$ echo $?
137140
0
@@ -148,7 +151,7 @@ an internal structure that is then dumped to the equivalent
148151
The syntax of this textual representation is documented in the man page of
149152
```ASN1_generate_nconf(3)```:
150153

151-
```bash
154+
```console
152155
$ man 3 ASN1_generate_nconf
153156
```
154157

@@ -215,6 +218,32 @@ Return codes:
215218
- ```1```: Command line arguments error.
216219
- ```2```: Unparseable line encountered.
217220
- ```3```: Indefinite length encoding detected.
221+
- ```4```: Unable to unwrap top-level SEQUENCE.
222+
223+
### Environment variables
224+
225+
You can instruct ```asn1template.pl``` to use an alternate ```openssl``` binary
226+
by setting the OPENSSL environment variable.
227+
Note that, depending on your setup, you might want to reference or preload
228+
matching dynamic libraries such as ```libcrypto.so``` and ```libssl.so``` by
229+
setting LD_LIBRARY_PATH or LD_PRELOAD.
230+
231+
```console
232+
$ export OPENSSL=/home/user/openssl-3.4.0/apps/openssl
233+
$ ${OPENSSL} version
234+
/home/user/openssl-3.4.0/apps/openssl: /lib/x86_64-linux-gnu/libssl.so.3: version `OPENSSL_3.4.0' not found (required by /home/user/openssl-3.4.0/apps/openssl)
235+
/home/user/openssl-3.4.0/apps/openssl: /lib/x86_64-linux-gnu/libssl.so.3: version `OPENSSL_3.2.0' not found (required by /home/user/openssl-3.4.0/apps/openssl)
236+
/home/user/openssl-3.4.0/apps/openssl: /lib/x86_64-linux-gnu/libcrypto.so.3: version `OPENSSL_3.3.0' not found (required by /home/user/openssl-3.4.0/apps/openssl)
237+
/home/user/openssl-3.4.0/apps/openssl: /lib/x86_64-linux-gnu/libcrypto.so.3: version `OPENSSL_3.4.0' not found (required by /home/user/openssl-3.4.0/apps/openssl)
238+
/home/user/openssl-3.4.0/apps/openssl: /lib/x86_64-linux-gnu/libcrypto.so.3: version `OPENSSL_3.2.0' not found (required by /home/user/openssl-3.4.0/apps/openssl)
239+
$ export LD_LIBRARY_PATH=/home/user/openssl-3.4.0
240+
$ ${OPENSSL} version
241+
OpenSSL 3.4.0 22 Oct 2024 (Library: OpenSSL 3.4.0 22 Oct 2024)
242+
$ ./asn1template.pl --pem /etc/ssl/certs/Amazon_Root_CA_3.pem | tee Amazon_Root_CA_3.tpl
243+
asn1 = SEQUENCE:seq1@0-4-438
244+
[seq1@0-4-438]
245+
[...]
246+
```
218247

219248
### Multi-root data structures
220249

@@ -224,8 +253,8 @@ depth 0.
224253

225254
Here is an example of such structure:
226255

227-
```
228-
$ openssl asn1parse -in TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der -inform D -i
256+
```console
257+
$ openssl asn1parse -in 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der' -inform D -i
229258
0:d=0 hl=3 l= 159 cons: cont [ 0 ]
230259
[...]
231260
162:d=0 hl=4 l= 775 cons: cont [ 16 ]
@@ -241,19 +270,19 @@ $ openssl asn1parse -in TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der -inform D -
241270
The ```-genconf``` option of the ```asn1parse``` OpenSSL app is not able to
242271
generate such multi-root structures. In order to deal with this issue, the
243272
```asn1template.pl``` command, with its ```--multi-root``` option, produces a
244-
template that wraps the concatenated structures into a top level SEQUENCE.
245-
This wrapping sequence can then be stripped using the ```unwrap_multiroot.pl```
246-
command after template edition.
273+
template that wraps the concatenated structures into a top-level SEQUENCE.
274+
This wrapping sequence can then be stripped using the ```--unwrap``` option
275+
after template edition.
247276

248277
Here is a full example, based on an eSIM test file
249278
(coming from https://github.com/GSMATerminals/Generic-eUICC-Test-Profile-for-Device-Testing-Public/):
250279

251-
```
252-
$ ./asn1template.pl --multi-root TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der > TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl
253-
$ openssl asn1parse -genconf TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl -out TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der
254-
$ ./unwrap_multiroot.pl TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der
255-
Output written to file "TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der.unwrapped".
256-
$ diff TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der TS48\ V5.0\ eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der.unwrapped
280+
```console
281+
$ ./asn1template.pl --multi-root 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der' > 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl'
282+
$ openssl asn1parse -genconf 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl' -out 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der'
283+
$ ./asn1template.pl --unwrap 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der'
284+
Output written to file "TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der.unwrapped" in DER format.
285+
$ diff 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der' 'TS48 V5.0 eSIM_GTP_SAIP2.3_BERTLV_SUCI.der.tpl.der.unwrapped'
257286
$ echo $?
258287
0
259288
```
@@ -262,7 +291,7 @@ $ echo $?
262291

263292
A mostly complete test script can be executed from project root:
264293

265-
```
294+
```console
266295
$ ./tests/run_tests.sh
267296
```
268297

0 commit comments

Comments
 (0)