More Related Content Similar to A look inside the European Covid Green Certificate (Codemotion 2021) (20) More from Luciano Mammino (20) A look inside the European Covid Green Certificate (Codemotion 2021)1. A look inside the
European Covid Green Certiļ¬cate
Luciano Mammino ( )
@loige
2021-12-01
loige.link/green
1
5. Let me introduce myself ļ¬rst...
šI'm LucianoĀ ( šš )
Senior Architect @ fourTheorem (Dublin )
3
6. Let me introduce myself ļ¬rst...
šI'm LucianoĀ ( šš )
Senior Architect @ fourTheorem (Dublin )
nodejsdp.link
šCo-Author of Node.js Design PatternsĀ š
3
7. Let me introduce myself ļ¬rst...
šI'm LucianoĀ ( šš )
Senior Architect @ fourTheorem (Dublin )
nodejsdp.link
šCo-Author of Node.js Design PatternsĀ š
Let's connect!
Ā (blog)
Ā (twitter)
Ā (twitch)
Ā (github)
loige.co
@loige
loige
lmammino
3
8. We are business focused technologists that
deliver.
Ā | Ā |
Accelerated Serverless AI as a Service Platform Modernisation
We are hiring: do you want to ?
work with us
loige 4
11. Disclaimers
loige
š¤I am not involved with the DGC working group
Ā
š¢COVID has been tough on everyone,
Ā Ā Ā we'll try to focus only on the tech here!
5
13. Agenda + Goals
loige
1. Needs and principles
2. šCryptographic model
3. š¦The data
4. š§
Layers of encoding
5. š Decoding in Rust
6
14. Agenda + Goals
loige
1. Needs and principles
2. šCryptographic model
3. š¦The data
4. š§
Layers of encoding
5. š Decoding in Rust
š¤ØLearn some cool technologies
š§Learn a tiny bit of Rust
š¤Be nerdy and have fun!
6
15. The need for a digital certiļ¬cate in
the COVID age
loige 7
16. The need for a digital certiļ¬cate in
the COVID age
loige 8
17. The need for a digital certiļ¬cate in
the COVID age
loige
š·We need a system to quickly provide a proof against COVID
Ā Ā Ā (Vaccination, negative test, proof of recovery)Ā
8
18. The need for a digital certiļ¬cate in
the COVID age
loige
š·We need a system to quickly provide a proof against COVID
Ā Ā Ā (Vaccination, negative test, proof of recovery)Ā
It needs to be personal, easy to carry around (digital),
Ā Ā Ā Ā easy to issue and to validate
8
19. The need for a digital certiļ¬cate in
the COVID age
loige
š·We need a system to quickly provide a proof against COVID
Ā Ā Ā (Vaccination, negative test, proof of recovery)Ā
It needs to be personal, easy to carry around (digital),
Ā Ā Ā Ā easy to issue and to validate
šIt needs to be secure against forgery and work across countries
8
20. The EU Covid Green Pass
a.k.a.Ā
Electronic Health Certiļ¬cates
(HCERT)
Ā
loige.link/hcert-spec
loige 9
23. Electronic Health Certiļ¬cates (HCERT)
Requirements & Guiding Principles
loige
āSigned data with machine readable content
šUse compact encoding
10
24. Electronic Health Certiļ¬cates (HCERT)
Requirements & Guiding Principles
loige
āSigned data with machine readable content
šUse compact encoding
š¤²Based on open standards
10
37. What's inside a certiļ¬cate?
loige
Cryptographic header (Key Id, Algorithm)
13
38. What's inside a certiļ¬cate?
loige
DGC container
Cryptographic header (Key Id, Algorithm)
13
39. What's inside a certiļ¬cate?
loige
DGC container
Cryptographic header (Key Id, Algorithm)
Cryptographic Signature
13
40. What's inside a certiļ¬cate?
loige
DGC container
Cryptographic header (Key Id, Algorithm)
Cryptographic Signature
Header (Issuer, Issue date, expiry date)
13
41. What's inside a certiļ¬cate?
loige
DGC container
Cryptographic header (Key Id, Algorithm)
Cryptographic Signature
Header (Issuer, Issue date, expiry date)
13
Certiļ¬cates list
Personal data (name, surname, DoB)
42. What's inside a certiļ¬cate?
loige
DGC container
Cryptographic header (Key Id, Algorithm)
Cryptographic Signature
Header (Issuer, Issue date, expiry date)
13
Certiļ¬cates list
vaccine, test, or recovery data
Personal data (name, surname, DoB)
45. {
"1": "DK",
"4": 1625054000,
"6": 1622462000,
"-260": {
"ver":"1.0.0",
"nam":{
"fn":"Klaus",
"fnt":"KLAUS",
"gn":"JĆørgensen",
"gnt":"JOERGENSEN"
},
"dob":"1983-01-06",
"v":[
{
"tg":"840539006",
"vp":"1119349007",
"mp":"EU/1/20/1528",
"ma":"ORG-100030215",
"dn":2,
"sd":2,
"dt":"2021-05-03",
"co":"DK",
"is":"Danish Health Data Authority",
"ci":"URN:UVCI:01:DK:B986830007345F99AE898FB82C6C61F2#A"
}
]
}
}
An example
loige loige.link/green-examples 15
46. {
"1": "DK",
"4": 1625054000,
"6": 1622462000,
"-260": {
"ver":"1.0.0",
"nam":{
"fn":"Klaus",
"fnt":"KLAUS",
"gn":"JĆørgensen",
"gnt":"JOERGENSEN"
},
"dob":"1983-01-06",
"v":[
{
"tg":"840539006",
"vp":"1119349007",
"mp":"EU/1/20/1528",
"ma":"ORG-100030215",
"dn":2,
"sd":2,
"dt":"2021-05-03",
"co":"DK",
"is":"Danish Health Data Authority",
"ci":"URN:UVCI:01:DK:B986830007345F99AE898FB82C6C61F2#A"
}
]
}
}
An example
loige loige.link/green-examples
DGC Header
15
47. {
"1": "DK",
"4": 1625054000,
"6": 1622462000,
"-260": {
"ver":"1.0.0",
"nam":{
"fn":"Klaus",
"fnt":"KLAUS",
"gn":"JĆørgensen",
"gnt":"JOERGENSEN"
},
"dob":"1983-01-06",
"v":[
{
"tg":"840539006",
"vp":"1119349007",
"mp":"EU/1/20/1528",
"ma":"ORG-100030215",
"dn":2,
"sd":2,
"dt":"2021-05-03",
"co":"DK",
"is":"Danish Health Data Authority",
"ci":"URN:UVCI:01:DK:B986830007345F99AE898FB82C6C61F2#A"
}
]
}
}
An example
loige loige.link/green-examples
Personal info
DGC Header
15
48. {
"1": "DK",
"4": 1625054000,
"6": 1622462000,
"-260": {
"ver":"1.0.0",
"nam":{
"fn":"Klaus",
"fnt":"KLAUS",
"gn":"JĆørgensen",
"gnt":"JOERGENSEN"
},
"dob":"1983-01-06",
"v":[
{
"tg":"840539006",
"vp":"1119349007",
"mp":"EU/1/20/1528",
"ma":"ORG-100030215",
"dn":2,
"sd":2,
"dt":"2021-05-03",
"co":"DK",
"is":"Danish Health Data Authority",
"ci":"URN:UVCI:01:DK:B986830007345F99AE898FB82C6C61F2#A"
}
]
}
}
An example
loige loige.link/green-examples
Personal info
Vaccine info
DGC Header
15
62. loige
Allows to encode binary data in text format (ASCII)
Like Base64, but it uses 45 characters instead:
Base45
19
63. loige
Allows to encode binary data in text format (ASCII)
Like Base64, but it uses 45 characters instead:
loige.link/base45-explained
Base45
19
68. Base45
loige
01001001 00100000 01100111
01101111 01110100 00100000
01101101 01111001 00100000
01110011 01101000 01101111
01110100 01110011 00100000
11011000 00111101
UTF8 (17 bytes)
I got my shots š
Hex (38 bytes)
49 20 67 6f 74 20 6d 79 20 73 68
6f 74 73 20 f0 9f 92 89
Some binary data
20
69. Base45
loige
01001001 00100000 01100111
01101111 01110100 00100000
01101101 01111001 00100000
01110011 01101000 01101111
01110100 01110011 00100000
11011000 00111101
UTF8 (17 bytes)
I got my shots š
Hex (38 bytes)
49 20 67 6f 74 20 6d 79 20 73 68
6f 74 73 20 f0 9f 92 89
Base64 (28 bytes)
SSBnb3QgbXkgc2hvdHMg8J+SiQ==
Some binary data
20
70. Base45
loige
01001001 00100000 01100111
01101111 01110100 00100000
01101101 01111001 00100000
01110011 01101000 01101111
01110100 01110011 00100000
11011000 00111101
UTF8 (17 bytes)
I got my shots š
Hex (38 bytes)
49 20 67 6f 74 20 6d 79 20 73 68
6f 74 73 20 f0 9f 92 89
Base64 (28 bytes)
SSBnb3QgbXkgc2hvdHMg8J+SiQ==
Base45 (29 bytes)
0B9J3DSUEZ$DR4459DLWEH74Z7K23
Some binary data
20
71. loige
loige.link/base45-rfc
"A QR-code is used to encode text as a graphical image. [...] QR-codes
cannot be used to encode arbitrary binary data directly.Ā [...] Compared
to already established Base64, Base32 and Base16 encoding schemes
[...], the Base45 scheme described in this document offer a more
compact QR-code encoding"
Base45
21
77. Zlib compression
loige
"zlib is designed to be a free, general-purpose, legally
unencumbered -- that is, not covered by any patents -- lossless
data-compression library for use on virtually any computer
hardware and operating system"
zlib.net
24
88. JSON
loige
A schema-less data format where a value can be:
Null
Boolean
Number
String
Array
Object
null
true
-17.34
"A programmer walks into a bar..."
["foo", 1.23, null, false, [22]]
{"foo": "bar", "manyvals": [1,2,3], "nested": {}}
30
89. CBOR
loige
A schema-less binaryĀ data format where a value can be:
Null
Boolean
Number
String Text
Array
Object Map
F6
F5
fbc031570a3d70a3d7
7820412070726f6772616d6d65722077616c6b7320696e746f2061206261722e2e2e
8563666f6ffb3ff3ae147ae147aef6f48116
a363666f6f63626172686d616e7976616c7383010203666e6573746564a0
31
106. COSE
loige
CBOR Object Signing and Encryption
COSE (inspired by ) deļ¬nes CBOR-based protocols for:
JOSE
Encrypted data
Cryptographic signed data
35
107. COSE
loige
CBOR Object Signing and Encryption
COSE (inspired by ) deļ¬nes CBOR-based protocols for:
JOSE
Encrypted data
Cryptographic signed data
MACed data
35
111. CWT
loige
Like but for CBOR
JWT
Deļ¬nes a protocol for transferring claims between parties
CBOR Web Token
36
112. CWT
loige
Like but for CBOR
JWT
Deļ¬nes a protocol for transferring claims between parties
CBOR Web Token
Claims are digitally signed for authenticity
36
113. CWT
loige
Like but for CBOR
JWT
loige.link/cwt-rfc
Deļ¬nes a protocol for transferring claims between parties
CBOR Web Token
Claims are digitally signed for authenticity
36
117. CWT
loige
A CWT is made of 4 parts:
Protected header
CBOR Web Token
Non protected header
37
118. CWT
loige
A CWT is made of 4 parts:
Protected header
CBOR Web Token
Non protected header
Payload
37
119. CWT
loige
A CWT is made of 4 parts:
Protected header
CBOR Web Token
Non protected header
Payload
Signature
37
120. CWT
loige
A CWT is encoded as a (tagged) CBOR array with 4 values:
Protected header (binary string)
CBOR Web Token
Non protected headerĀ (map)
PayloadĀ (binary string)
SignatureĀ (binary string)
38
137. loige
CWT payload
{
"1": "DK",
"4": 1625054000,
"6": 1622462000,
"-260": {
"ver":"1.0.0",
"nam":{
"fn":"Klaus",
"fnt":"KLAUS",
"gn":"JĆørgensen",
"gnt":"JOERGENSEN"
},
"dob":"1983-01-06",
"v":[
{
"tg":"840539006",
"vp":"1119349007",
"mp":"EU/1/20/1528",
"ma":"ORG-100030215",
"dn":2,
"sd":2,
"dt":"2021-05-03",
"co":"DK",
"is":"Danish Health Data Authority",
"ci":"URN:UVCI:01:DK:B986830007345F99AE898FB82C6C61F2#A"
}
]
}
}
Binary String follows (CBOR Encoded)
CBOR decode
Ā Ā (to JSON)
40
138. loige
CWT payload
{
"1": "DK",
"4": 1625054000,
"6": 1622462000,
"-260": {
"ver":"1.0.0",
"nam":{
"fn":"Klaus",
"fnt":"KLAUS",
"gn":"JĆørgensen",
"gnt":"JOERGENSEN"
},
"dob":"1983-01-06",
"v":[
{
"tg":"840539006",
"vp":"1119349007",
"mp":"EU/1/20/1528",
"ma":"ORG-100030215",
"dn":2,
"sd":2,
"dt":"2021-05-03",
"co":"DK",
"is":"Danish Health Data Authority",
"ci":"URN:UVCI:01:DK:B986830007345F99AE898FB82C6C61F2#A"
}
]
}
}
Binary String follows (CBOR Encoded)
CBOR decode
Ā Ā (to JSON)
40
141. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
41
142. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
3. Zlib decompress
41
143. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
3. Zlib decompress
4. Parse CWT
41
144. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
3. Zlib decompress
4. Parse CWT
5. Parse CWT Payload as CBOR
41
145. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
3. Zlib decompress
4. Parse CWT
5. Parse CWT Payload as CBOR
6. Party hard! š„³
41
146. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
3. Zlib decompress
4. Parse CWT
5. Parse CWT Payload as CBOR
6. Party hard! š„³
41
147. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
3. Zlib decompress
4. Parse CWT
5. Parse CWT Payload as CBOR
6. Party hard! š„³
Hey, let's implement this...
41
148. How to decodeĀ - quick recap
loige
1. Remove "HC1:" preļ¬x
2. Base45 decode
3. Zlib decompress
4. Parse CWT
5. Parse CWT Payload as CBOR
6. Party hard! š„³
Hey, let's implement this... in Rust!
41
150. // src/main.rs
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
todo!()
// 1. Remove "HC1:" prefix
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
1
2
3
4
5
6
7
8
9
10
11
loige 43
151. // src/main.rs
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
todo!()
// 1. Remove "HC1:" prefix
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
1
2
3
4
5
6
7
8
9
10
11
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
// src/main.rs
1
2
fn main() {
3
4
todo!()
5
// 1. Remove "HC1:" prefix
6
// 2. Base45 decode
7
// 3. Zlib decompress
8
// 4. Parse CWT
9
// 5. Parse CWT Payload as CBOR
10
}
11
loige 43
152. // src/main.rs
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
todo!()
// 1. Remove "HC1:" prefix
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
1
2
3
4
5
6
7
8
9
10
11
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
// src/main.rs
1
2
fn main() {
3
4
todo!()
5
// 1. Remove "HC1:" prefix
6
// 2. Base45 decode
7
// 3. Zlib decompress
8
// 4. Parse CWT
9
// 5. Parse CWT Payload as CBOR
10
}
11
todo!()
// 1. Remove "HC1:" prefix
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
// src/main.rs
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
5
6
7
8
9
10
}
11
loige 43
153. // src/main.rs
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
todo!()
// 1. Remove "HC1:" prefix
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
1
2
3
4
5
6
7
8
9
10
11
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
// src/main.rs
1
2
fn main() {
3
4
todo!()
5
// 1. Remove "HC1:" prefix
6
// 2. Base45 decode
7
// 3. Zlib decompress
8
// 4. Parse CWT
9
// 5. Parse CWT Payload as CBOR
10
}
11
todo!()
// 1. Remove "HC1:" prefix
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
// src/main.rs
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
5
6
7
8
9
10
}
11
// src/main.rs
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
todo!()
// 1. Remove "HC1:" prefix
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
1
2
3
4
5
6
7
8
9
10
11
loige 43
154. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
todo!()
// remove "HC1:" prefix and return remaining string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
loige 44
155. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
todo!()
// remove "HC1:" prefix and return remaining string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let no_prefix = remove_prefix(cert_data);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
3
todo!();
4
// 2. Base45 decode
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn remove_prefix(data: &str) -> &str {
11
todo!()
12
// remove "HC1:" prefix and return remaining string
13
}
14
loige 44
156. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
todo!()
// remove "HC1:" prefix and return remaining string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let no_prefix = remove_prefix(cert_data);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
3
todo!();
4
// 2. Base45 decode
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn remove_prefix(data: &str) -> &str {
11
todo!()
12
// remove "HC1:" prefix and return remaining string
13
}
14
fn remove_prefix(data: &str) -> &str {
todo!()
// remove "HC1:" prefix and return remaining string
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
todo!();
4
// 2. Base45 decode
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
loige 44
157. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
todo!()
// remove "HC1:" prefix and return remaining string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let no_prefix = remove_prefix(cert_data);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
3
todo!();
4
// 2. Base45 decode
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn remove_prefix(data: &str) -> &str {
11
todo!()
12
// remove "HC1:" prefix and return remaining string
13
}
14
fn remove_prefix(data: &str) -> &str {
todo!()
// remove "HC1:" prefix and return remaining string
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
todo!();
4
// 2. Base45 decode
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
todo!()
// remove "HC1:" prefix and return remaining string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
loige 44
158. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
if data.len() < 4 || !data.starts_with("HC1:") {
panic!("Invalid prefix"); // IRL use a Result!
}
&data[4..]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loige 45
159. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
if data.len() < 4 || !data.starts_with("HC1:") {
panic!("Invalid prefix"); // IRL use a Result!
}
&data[4..]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if data.len() < 4 || !data.starts_with("HC1:") {
panic!("Invalid prefix"); // IRL use a Result!
}
&data[4..]
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
todo!();
4
// 2. Base45 decode
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn remove_prefix(data: &str) -> &str {
11
12
13
14
15
16
}
17
loige 45
160. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
if data.len() < 4 || !data.starts_with("HC1:") {
panic!("Invalid prefix"); // IRL use a Result!
}
&data[4..]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if data.len() < 4 || !data.starts_with("HC1:") {
panic!("Invalid prefix"); // IRL use a Result!
}
&data[4..]
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
todo!();
4
// 2. Base45 decode
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn remove_prefix(data: &str) -> &str {
11
12
13
14
15
16
}
17
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
todo!();
// 2. Base45 decode
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn remove_prefix(data: &str) -> &str {
if data.len() < 4 || !data.starts_with("HC1:") {
panic!("Invalid prefix"); // IRL use a Result!
}
&data[4..]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loige 45
161. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
todo!()
// parse the string as base45 encoded and return the
// resulting raw bytes
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loige 46
162. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
todo!()
// parse the string as base45 encoded and return the
// resulting raw bytes
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let decoded = decode_base45(no_prefix);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
4
todo!()
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decode_base45(data: &str) -> Vec<u8> {
11
todo!()
12
// parse the string as base45 encoded and return the
13
// resulting raw bytes
14
}
15
16
// ...
17
loige 46
163. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
todo!()
// parse the string as base45 encoded and return the
// resulting raw bytes
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let decoded = decode_base45(no_prefix);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
4
todo!()
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decode_base45(data: &str) -> Vec<u8> {
11
todo!()
12
// parse the string as base45 encoded and return the
13
// resulting raw bytes
14
}
15
16
// ...
17
fn decode_base45(data: &str) -> Vec<u8> {
todo!()
// parse the string as base45 encoded and return the
// resulting raw bytes
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
todo!()
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
15
16
// ...
17
loige 46
164. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
todo!()
// parse the string as base45 encoded and return the
// resulting raw bytes
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let decoded = decode_base45(no_prefix);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
4
todo!()
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decode_base45(data: &str) -> Vec<u8> {
11
todo!()
12
// parse the string as base45 encoded and return the
13
// resulting raw bytes
14
}
15
16
// ...
17
fn decode_base45(data: &str) -> Vec<u8> {
todo!()
// parse the string as base45 encoded and return the
// resulting raw bytes
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
todo!()
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
15
16
// ...
17
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
todo!()
// parse the string as base45 encoded and return the
// resulting raw bytes
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loige 46
167. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
base45::decode(data).unwrap() // IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
loige 48
168. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
base45::decode(data).unwrap() // IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
base45::decode(data).unwrap() // IRL use a Result!
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
todo!()
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decode_base45(data: &str) -> Vec<u8> {
11
12
}
13
14
// ...
15
loige 48
169. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
base45::decode(data).unwrap() // IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
base45::decode(data).unwrap() // IRL use a Result!
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
todo!()
5
// 3. Zlib decompress
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decode_base45(data: &str) -> Vec<u8> {
11
12
}
13
14
// ...
15
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
todo!()
// 3. Zlib decompress
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decode_base45(data: &str) -> Vec<u8> {
base45::decode(data).unwrap() // IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
loige 48
170. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
todo!()
// decompress using zlib inflate
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
loige 49
171. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
todo!()
// decompress using zlib inflate
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let decompressed = decompress(decoded);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
5
todo!()
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decompress(data: Vec<u8>) -> Vec<u8> {
11
todo!()
12
// decompress using zlib inflate
13
}
14
15
// ...
16
loige 49
172. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
todo!()
// decompress using zlib inflate
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let decompressed = decompress(decoded);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
5
todo!()
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decompress(data: Vec<u8>) -> Vec<u8> {
11
todo!()
12
// decompress using zlib inflate
13
}
14
15
// ...
16
fn decompress(data: Vec<u8>) -> Vec<u8> {
todo!()
// decompress using zlib inflate
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
todo!()
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
15
// ...
16
loige 49
173. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
todo!()
// decompress using zlib inflate
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let decompressed = decompress(decoded);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
5
todo!()
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decompress(data: Vec<u8>) -> Vec<u8> {
11
todo!()
12
// decompress using zlib inflate
13
}
14
15
// ...
16
fn decompress(data: Vec<u8>) -> Vec<u8> {
todo!()
// decompress using zlib inflate
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
todo!()
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
15
// ...
16
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
todo!()
// decompress using zlib inflate
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
loige 49
176. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
inflate::inflate_bytes_zlib(data.as_slice()).unwrap()
// IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
loige 51
177. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
inflate::inflate_bytes_zlib(data.as_slice()).unwrap()
// IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
inflate::inflate_bytes_zlib(data.as_slice()).unwrap()
// IRL use a Result!
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
todo!()
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decompress(data: Vec<u8>) -> Vec<u8> {
11
12
13
}
14
15
// ...
16
loige 51
178. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
inflate::inflate_bytes_zlib(data.as_slice()).unwrap()
// IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
inflate::inflate_bytes_zlib(data.as_slice()).unwrap()
// IRL use a Result!
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
todo!()
6
// 4. Parse CWT
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn decompress(data: Vec<u8>) -> Vec<u8> {
11
12
13
}
14
15
// ...
16
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
todo!()
// 4. Parse CWT
// 5. Parse CWT Payload as CBOR
}
fn decompress(data: Vec<u8>) -> Vec<u8> {
inflate::inflate_bytes_zlib(data.as_slice()).unwrap()
// IRL use a Result!
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
loige 51
179. Are we on the right track?
loige
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
println!("{}", String::from_utf8_lossy(&decompressed));
}
// ...
1
2
3
4
5
6
7
8
9
10
52
180. Are we on the right track?
loige
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
println!("{}", String::from_utf8_lossy(&decompressed));
}
// ...
1
2
3
4
5
6
7
8
9
10
println!("{}", String::from_utf8_lossy(&decompressed));
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
6
7
}
8
9
// ...
10
52
182. Are we on the right track?
loige
We are starting to see some
readable info! š¤© 53
183. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
todo!()
// Parse raw bytes as CBOR.
// Extract and return the raw bytes representing
// the CWT payload
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
loige 54
184. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
todo!()
// Parse raw bytes as CBOR.
// Extract and return the raw bytes representing
// the CWT payload
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let cwt_payload = get_cwt_payload(decompressed);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
6
todo!()
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
11
todo!()
12
// Parse raw bytes as CBOR.
13
// Extract and return the raw bytes representing
14
// the CWT payload
15
}
16
17
// ...
18
loige 54
185. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
todo!()
// Parse raw bytes as CBOR.
// Extract and return the raw bytes representing
// the CWT payload
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let cwt_payload = get_cwt_payload(decompressed);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
6
todo!()
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
11
todo!()
12
// Parse raw bytes as CBOR.
13
// Extract and return the raw bytes representing
14
// the CWT payload
15
}
16
17
// ...
18
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
todo!()
// Parse raw bytes as CBOR.
// Extract and return the raw bytes representing
// the CWT payload
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
let cwt_payload = get_cwt_payload(decompressed);
6
todo!()
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
15
16
17
// ...
18
loige 54
186. fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
todo!()
// Parse raw bytes as CBOR.
// Extract and return the raw bytes representing
// the CWT payload
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let cwt_payload = get_cwt_payload(decompressed);
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
6
todo!()
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
11
todo!()
12
// Parse raw bytes as CBOR.
13
// Extract and return the raw bytes representing
14
// the CWT payload
15
}
16
17
// ...
18
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
todo!()
// Parse raw bytes as CBOR.
// Extract and return the raw bytes representing
// the CWT payload
}
fn main() {
1
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
2
let no_prefix = remove_prefix(cert_data);
3
let decoded = decode_base45(no_prefix);
4
let decompressed = decompress(decoded);
5
let cwt_payload = get_cwt_payload(decompressed);
6
todo!()
7
// 5. Parse CWT Payload as CBOR
8
}
9
10
11
12
13
14
15
16
17
// ...
18
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
todo!()
// Parse raw bytes as CBOR.
// Extract and return the raw bytes representing
// the CWT payload
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
loige 54
189. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
let parsed: Value = from_reader(data.as_slice()).unwrap();
println!("{:?}", parsed);
todo!()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
loige 56
190. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
let parsed: Value = from_reader(data.as_slice()).unwrap();
println!("{:?}", parsed);
todo!()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
todo!()
9
// 5. Parse CWT Payload as CBOR
10
}
11
12
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
13
let parsed: Value = from_reader(data.as_slice()).unwrap();
14
println!("{:?}", parsed);
15
todo!()
16
}
17
18
// ...
19
loige 56
191. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
todo!()
// 5. Parse CWT Payload as CBOR
}
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
let parsed: Value = from_reader(data.as_slice()).unwrap();
println!("{:?}", parsed);
todo!()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
todo!()
9
// 5. Parse CWT Payload as CBOR
10
}
11
12
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
13
let parsed: Value = from_reader(data.as_slice()).unwrap();
14
println!("{:?}", parsed);
15
todo!()
16
}
17
18
// ...
19
let parsed: Value = from_reader(data.as_slice()).unwrap();
println!("{:?}", parsed);
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
todo!()
9
// 5. Parse CWT Payload as CBOR
10
}
11
12
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
13
14
15
todo!()
16
}
17
18
// ...
19
loige 56
200. // ...
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
// IRL avoid .unwrap() like hell and propagate errors correctly!
let parsed: Value = from_reader(data.as_slice()).unwrap();
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
let arr = arr.as_array().unwrap();
let payload = arr[2].as_bytes().unwrap();
payload.clone()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
loige 58
201. // ...
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
// IRL avoid .unwrap() like hell and propagate errors correctly!
let parsed: Value = from_reader(data.as_slice()).unwrap();
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
let arr = arr.as_array().unwrap();
let payload = arr[2].as_bytes().unwrap();
payload.clone()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
let parsed: Value = from_reader(data.as_slice()).unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
loige 58
202. // ...
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
// IRL avoid .unwrap() like hell and propagate errors correctly!
let parsed: Value = from_reader(data.as_slice()).unwrap();
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
let arr = arr.as_array().unwrap();
let payload = arr[2].as_bytes().unwrap();
payload.clone()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
let parsed: Value = from_reader(data.as_slice()).unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
6
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
loige 58
203. // ...
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
// IRL avoid .unwrap() like hell and propagate errors correctly!
let parsed: Value = from_reader(data.as_slice()).unwrap();
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
let arr = arr.as_array().unwrap();
let payload = arr[2].as_bytes().unwrap();
payload.clone()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
let parsed: Value = from_reader(data.as_slice()).unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
6
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let arr = arr.as_array().unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
loige 58
204. // ...
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
// IRL avoid .unwrap() like hell and propagate errors correctly!
let parsed: Value = from_reader(data.as_slice()).unwrap();
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
let arr = arr.as_array().unwrap();
let payload = arr[2].as_bytes().unwrap();
payload.clone()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
let parsed: Value = from_reader(data.as_slice()).unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
6
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let arr = arr.as_array().unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let payload = arr[2].as_bytes().unwrap();
payload.clone()
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
let arr = arr.as_array().unwrap();
8
9
10
}
11
12
// ...
13
loige 58
205. // ...
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
// IRL avoid .unwrap() like hell and propagate errors correctly!
let parsed: Value = from_reader(data.as_slice()).unwrap();
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
let arr = arr.as_array().unwrap();
let payload = arr[2].as_bytes().unwrap();
payload.clone()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
let parsed: Value = from_reader(data.as_slice()).unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
6
7
let arr = arr.as_array().unwrap();
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let arr = arr.as_array().unwrap();
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
8
let payload = arr[2].as_bytes().unwrap();
9
payload.clone()
10
}
11
12
// ...
13
let payload = arr[2].as_bytes().unwrap();
payload.clone()
// ...
1
2
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
3
// IRL avoid .unwrap() like hell and propagate errors correctly!
4
let parsed: Value = from_reader(data.as_slice()).unwrap();
5
let (tag, arr) = parsed.as_tag().unwrap();
6
assert_eq!(tag, 18);
7
let arr = arr.as_array().unwrap();
8
9
10
}
11
12
// ...
13
// ...
fn get_cwt_payload(data: Vec<u8>) -> Vec<u8> {
// IRL avoid .unwrap() like hell and propagate errors correctly!
let parsed: Value = from_reader(data.as_slice()).unwrap();
let (tag, arr) = parsed.as_tag().unwrap();
assert_eq!(tag, 18);
let arr = arr.as_array().unwrap();
let payload = arr[2].as_bytes().unwrap();
payload.clone()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
loige 58
206. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
// parse the binary data as CBOR
todo!()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loige 59
207. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
// parse the binary data as CBOR
todo!()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let parsed_payload = parse_cwt_payload(cwt_payload);
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
9
}
10
11
fn parse_cwt_payload(data: Vec<u8>) -> Value {
12
// parse the binary data as CBOR
13
todo!()
14
}
15
16
// ...
17
loige 59
208. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
// parse the binary data as CBOR
todo!()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let parsed_payload = parse_cwt_payload(cwt_payload);
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
9
}
10
11
fn parse_cwt_payload(data: Vec<u8>) -> Value {
12
// parse the binary data as CBOR
13
todo!()
14
}
15
16
// ...
17
fn parse_cwt_payload(data: Vec<u8>) -> Value {
// parse the binary data as CBOR
todo!()
}
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
let parsed_payload = parse_cwt_payload(cwt_payload);
9
}
10
11
12
13
14
15
16
// ...
17
loige 59
209. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{:#?}", parsed_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
from_reader(data.as_slice()).unwrap()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loige 60
210. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{:#?}", parsed_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
from_reader(data.as_slice()).unwrap()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from_reader(data.as_slice()).unwrap()
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
let parsed_payload = parse_cwt_payload(cwt_payload);
9
println!("{:#?}", parsed_payload);
10
}
11
12
fn parse_cwt_payload(data: Vec<u8>) -> Value {
13
14
}
15
16
// ...
17
loige 60
211. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{:#?}", parsed_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
from_reader(data.as_slice()).unwrap()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from_reader(data.as_slice()).unwrap()
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
let parsed_payload = parse_cwt_payload(cwt_payload);
9
println!("{:#?}", parsed_payload);
10
}
11
12
fn parse_cwt_payload(data: Vec<u8>) -> Value {
13
14
}
15
16
// ...
17
println!("{:#?}", parsed_payload);
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
let parsed_payload = parse_cwt_payload(cwt_payload);
9
10
}
11
12
fn parse_cwt_payload(data: Vec<u8>) -> Value {
13
from_reader(data.as_slice()).unwrap()
14
}
15
16
// ...
17
loige 60
212. use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{:#?}", parsed_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
from_reader(data.as_slice()).unwrap()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from_reader(data.as_slice()).unwrap()
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
let parsed_payload = parse_cwt_payload(cwt_payload);
9
println!("{:#?}", parsed_payload);
10
}
11
12
fn parse_cwt_payload(data: Vec<u8>) -> Value {
13
14
}
15
16
// ...
17
println!("{:#?}", parsed_payload);
use ciborium::{de::from_reader, value::Value};
1
2
fn main() {
3
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
4
let no_prefix = remove_prefix(cert_data);
5
let decoded = decode_base45(no_prefix);
6
let decompressed = decompress(decoded);
7
let cwt_payload = get_cwt_payload(decompressed);
8
let parsed_payload = parse_cwt_payload(cwt_payload);
9
10
}
11
12
fn parse_cwt_payload(data: Vec<u8>) -> Value {
13
from_reader(data.as_slice()).unwrap()
14
}
15
16
// ...
17
use ciborium::{de::from_reader, value::Value};
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{:#?}", parsed_payload);
}
fn parse_cwt_payload(data: Vec<u8>) -> Value {
from_reader(data.as_slice()).unwrap()
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loige 60
216. Ok, let's make it more readable... š
loige
cargo add serde_json
62
217. use ciborium::{de::from_reader, value::Value};
use serde_json::to_string_pretty;
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{}", to_string_pretty(&parsed_payload).unwrap());
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
loige 63
218. use ciborium::{de::from_reader, value::Value};
use serde_json::to_string_pretty;
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{}", to_string_pretty(&parsed_payload).unwrap());
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
use serde_json::to_string_pretty;
use ciborium::{de::from_reader, value::Value};
1
2
3
fn main() {
4
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
5
let no_prefix = remove_prefix(cert_data);
6
let decoded = decode_base45(no_prefix);
7
let decompressed = decompress(decoded);
8
let cwt_payload = get_cwt_payload(decompressed);
9
let parsed_payload = parse_cwt_payload(cwt_payload);
10
println!("{}", to_string_pretty(&parsed_payload).unwrap());
11
}
12
13
// ...
14
loige 63
219. use ciborium::{de::from_reader, value::Value};
use serde_json::to_string_pretty;
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{}", to_string_pretty(&parsed_payload).unwrap());
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
use serde_json::to_string_pretty;
use ciborium::{de::from_reader, value::Value};
1
2
3
fn main() {
4
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
5
let no_prefix = remove_prefix(cert_data);
6
let decoded = decode_base45(no_prefix);
7
let decompressed = decompress(decoded);
8
let cwt_payload = get_cwt_payload(decompressed);
9
let parsed_payload = parse_cwt_payload(cwt_payload);
10
println!("{}", to_string_pretty(&parsed_payload).unwrap());
11
}
12
13
// ...
14
println!("{}", to_string_pretty(&parsed_payload).unwrap());
use ciborium::{de::from_reader, value::Value};
1
use serde_json::to_string_pretty;
2
3
fn main() {
4
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
5
let no_prefix = remove_prefix(cert_data);
6
let decoded = decode_base45(no_prefix);
7
let decompressed = decompress(decoded);
8
let cwt_payload = get_cwt_payload(decompressed);
9
let parsed_payload = parse_cwt_payload(cwt_payload);
10
11
}
12
13
// ...
14
loige 63
220. use ciborium::{de::from_reader, value::Value};
use serde_json::to_string_pretty;
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{}", to_string_pretty(&parsed_payload).unwrap());
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
use serde_json::to_string_pretty;
use ciborium::{de::from_reader, value::Value};
1
2
3
fn main() {
4
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
5
let no_prefix = remove_prefix(cert_data);
6
let decoded = decode_base45(no_prefix);
7
let decompressed = decompress(decoded);
8
let cwt_payload = get_cwt_payload(decompressed);
9
let parsed_payload = parse_cwt_payload(cwt_payload);
10
println!("{}", to_string_pretty(&parsed_payload).unwrap());
11
}
12
13
// ...
14
println!("{}", to_string_pretty(&parsed_payload).unwrap());
use ciborium::{de::from_reader, value::Value};
1
use serde_json::to_string_pretty;
2
3
fn main() {
4
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
5
let no_prefix = remove_prefix(cert_data);
6
let decoded = decode_base45(no_prefix);
7
let decompressed = decompress(decoded);
8
let cwt_payload = get_cwt_payload(decompressed);
9
let parsed_payload = parse_cwt_payload(cwt_payload);
10
11
}
12
13
// ...
14
use ciborium::{de::from_reader, value::Value};
use serde_json::to_string_pretty;
fn main() {
let cert_data = "HC1:NCFOXN%TSMAHN-H9QCGDSB5QPN9OO3:D4$X4-365KN-TMLV4
let no_prefix = remove_prefix(cert_data);
let decoded = decode_base45(no_prefix);
let decompressed = decompress(decoded);
let cwt_payload = get_cwt_payload(decompressed);
let parsed_payload = parse_cwt_payload(cwt_payload);
println!("{}", to_string_pretty(&parsed_payload).unwrap());
}
// ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
loige 63
224. A better (& more complete) implementation
as a Rust library
loige
github.com/rust-italia/dgc
66
226. Exercise for the viewer:
Try to validate the signature
loige
šYou can get the Public Key from the certiļ¬cate
here: loige.link/green-examples
67
227. Exercise for the viewer:
Try to validate the signature
loige
šYou can get the Public Key from the certiļ¬cate
here: loige.link/green-examples
šHere you can ļ¬nd more about how the CoseSign1
protocol works: loige.link/cose-sign-verif
67
228. Exercise for the viewer:
Try to validate the signature
loige
šYou can get the Public Key from the certiļ¬cate
here: loige.link/green-examples
šHere you can ļ¬nd more about how the CoseSign1
protocol works: loige.link/cose-sign-verif
š¦You could use a crate like for crypto!
ring
67
229. Exercise for the viewer:
Try to validate the signature
loige
šYou can get the Public Key from the certiļ¬cate
here: loige.link/green-examples
šHere you can ļ¬nd more about how the CoseSign1
protocol works: loige.link/cose-sign-verif
š¦You could use a crate like for crypto!
ring
(Spoiler: I implemented some of this stuff in my library!)
67
231. Is all this stuļ¬ legal? š°
loige
šYou can certainly look into your certiļ¬cate (and the
test certiļ¬cates!)
68
232. Is all this stuļ¬ legal? š°
loige
šYou can certainly look into your certiļ¬cate (and the
test certiļ¬cates!)
š£Looking into other people's certiļ¬cate will disclose
a lot of privacy-sensitive info (thread carefully)
68
233. Is all this stuļ¬ legal? š°
loige
šYou can certainly look into your certiļ¬cate (and the
test certiļ¬cates!)
š£Looking into other people's certiļ¬cate will disclose
a lot of privacy-sensitive info (thread carefully)
š²Building a validator app? Check your country's
regulation (especially if you need to store data!)
68
234. Cover Picture by on
ā¤ Ā Huge thanks to for some precius review sessions and many pull requests!
ā¤ Thanks to , , , , Ā for reviews and suggestions.
FPVmat A Unsplash
rust-italia
@gbinside @88_eugen @AlleviTommaso @npmccallum @pelger
loige
ānodejsdp.link
loige.link/green
THANK YOU!
ā¤
69