openpgp_card/ocard/data/
algo_info.rs

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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Algorithm Information [Spec section 4.4.3.11]

use std::convert::TryFrom;
use std::fmt;

use nom::branch::alt;
use nom::combinator::map;
use nom::{branch, bytes::complete as bytes, combinator, multi, sequence};

use crate::ocard::algorithm::{AlgorithmAttributes, AlgorithmInformation};
use crate::ocard::data::{algo_attrs, complete};
use crate::ocard::tlv;
use crate::ocard::KeyType;

impl AlgorithmInformation {
    pub fn for_keytype(&self, kt: KeyType) -> Vec<&AlgorithmAttributes> {
        self.0
            .iter()
            .filter(|(k, _)| *k == kt)
            .map(|(_, a)| a)
            .collect()
    }
}

impl fmt::Display for AlgorithmInformation {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for (kt, a) in &self.0 {
            let kt = match kt {
                KeyType::Signing => "SIG",
                KeyType::Decryption => "DEC",
                KeyType::Authentication => "AUT",
                KeyType::Attestation => "ATT",
            };
            writeln!(f, "{kt}: {a:?} ")?;
        }
        Ok(())
    }
}

fn key_type(input: &[u8]) -> nom::IResult<&[u8], KeyType> {
    alt((
        map(bytes::tag([0xc1]), |_| KeyType::Signing),
        map(bytes::tag([0xc2]), |_| KeyType::Decryption),
        map(bytes::tag([0xc3]), |_| KeyType::Authentication),
        map(bytes::tag([0xda]), |_| KeyType::Attestation),
    ))(input)
}

fn unknown(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> {
    Ok((&[], AlgorithmAttributes::Unknown(input.to_vec())))
}

fn parse_one(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> {
    let (input, a) = combinator::map(
        combinator::flat_map(tlv::length::length, bytes::take),
        |i| alt((combinator::all_consuming(algo_attrs::parse), unknown))(i),
    )(input)?;

    Ok((input, a?.1))
}

fn parse_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
    multi::many0(sequence::pair(key_type, parse_one))(input)
}

fn parse_tl_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
    let (input, (_, _, list)) =
        sequence::tuple((bytes::tag([0xfa]), tlv::length::length, parse_list))(input)?;

    Ok((input, list))
}

fn parse(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
    // Handle two variations of input format:
    // a) TLV format (e.g. YubiKey 5)
    // b) Plain list (e.g. Gnuk, FOSS-Store Smartcard 3.4)

    // -- Gnuk: do_alg_info (uint16_t tag, int with_tag)

    branch::alt((
        combinator::all_consuming(parse_list),
        combinator::all_consuming(parse_tl_list),
    ))(input)
}

impl TryFrom<&[u8]> for AlgorithmInformation {
    type Error = crate::Error;

    fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
        Ok(AlgorithmInformation(complete(parse(input))?))
    }
}

// test

#[cfg(test)]
mod test {
    use std::convert::TryFrom;

    use crate::ocard::algorithm::{
        AlgorithmAttributes::*, AlgorithmInformation, Curve::*, EccAttributes, RsaAttributes,
    };
    use crate::ocard::crypto::EccType::*;
    use crate::ocard::KeyType::*;

    #[test]
    fn test_gnuk() {
        let data = [
            0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0,
            0xc1, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b,
            0x81, 0x4, 0x0, 0xa, 0xc1, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1,
            0xc2, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc2, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0,
            0xc2, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc2, 0x6, 0x13, 0x2b,
            0x81, 0x4, 0x0, 0xa, 0xc2, 0xb, 0x12, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5,
            0x1, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20,
            0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13,
            0x2b, 0x81, 0x4, 0x0, 0xa, 0xc3, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf,
            0x1,
        ];

        let ai = AlgorithmInformation::try_from(&data[..]).unwrap();

        assert_eq!(
            ai,
            AlgorithmInformation(vec![
                (Signing, Rsa(RsaAttributes::new(2048, 32, 0))),
                (Signing, Rsa(RsaAttributes::new(4096, 32, 0))),
                (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
                (Signing, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
                (Signing, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
                (Decryption, Rsa(RsaAttributes::new(2048, 32, 0))),
                (Decryption, Rsa(RsaAttributes::new(4096, 32, 0))),
                (Decryption, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
                (Decryption, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
                (Decryption, Ecc(EccAttributes::new(ECDH, Curve25519, None))),
                (Authentication, Rsa(RsaAttributes::new(2048, 32, 0))),
                (Authentication, Rsa(RsaAttributes::new(4096, 32, 0))),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, Secp256k1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(EdDSA, Ed25519, None))
                )
            ])
        );
    }

    #[test]
    fn test_opgp_card_34() {
        let data = [
            0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x6, 0x1, 0xc, 0x0, 0x0, 0x20, 0x0,
            0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce,
            0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc1, 0x6, 0x13,
            0x2b, 0x81, 0x4, 0x0, 0x23, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1,
            0x7, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc1, 0xa, 0x13,
            0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd, 0xc2, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20,
            0x0, 0xc2, 0x6, 0x1, 0xc, 0x0, 0x0, 0x20, 0x0, 0xc2, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20,
            0x0, 0xc2, 0x9, 0x12, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc2, 0x6, 0x12,
            0x2b, 0x81, 0x4, 0x0, 0x22, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc2, 0xa,
            0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3,
            0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1,
            0x1, 0xd, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x6, 0x1, 0xc, 0x0, 0x0,
            0x20, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86,
            0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc3,
            0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8,
            0x1, 0x1, 0x7, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc3,
            0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd,
        ];

        let ai = AlgorithmInformation::try_from(&data[..]).unwrap();

        assert_eq!(
            ai,
            AlgorithmInformation(vec![
                (Signing, Rsa(RsaAttributes::new(2048, 32, 0))),
                (Signing, Rsa(RsaAttributes::new(3072, 32, 0))),
                (Signing, Rsa(RsaAttributes::new(4096, 32, 0))),
                (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
                (Signing, Ecc(EccAttributes::new(ECDSA, NistP384r1, None))),
                (Signing, Ecc(EccAttributes::new(ECDSA, NistP521r1, None))),
                (
                    Signing,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
                ),
                (
                    Signing,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
                ),
                (
                    Signing,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
                ),
                (Decryption, Rsa(RsaAttributes::new(2048, 32, 0))),
                (Decryption, Rsa(RsaAttributes::new(3072, 32, 0))),
                (Decryption, Rsa(RsaAttributes::new(4096, 32, 0))),
                (Decryption, Ecc(EccAttributes::new(ECDH, NistP256r1, None))),
                (Decryption, Ecc(EccAttributes::new(ECDH, NistP384r1, None))),
                (Decryption, Ecc(EccAttributes::new(ECDH, NistP521r1, None))),
                (
                    Decryption,
                    Ecc(EccAttributes::new(ECDH, BrainpoolP256r1, None))
                ),
                (
                    Decryption,
                    Ecc(EccAttributes::new(ECDH, BrainpoolP384r1, None))
                ),
                (
                    Decryption,
                    Ecc(EccAttributes::new(ECDH, BrainpoolP512r1, None))
                ),
                (Authentication, Rsa(RsaAttributes::new(2048, 32, 0))),
                (Authentication, Rsa(RsaAttributes::new(3072, 32, 0))),
                (Authentication, Rsa(RsaAttributes::new(4096, 32, 0))),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
                )
            ])
        );
    }

    #[test]
    fn test_yk5() {
        let data = [
            0xfa, 0x82, 0x1, 0xe2, 0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xc1, 0x6, 0x1, 0xc,
            0x0, 0x0, 0x11, 0x0, 0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xc1, 0x9, 0x13, 0x2a,
            0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22,
            0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0,
            0xa, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc1, 0xa, 0x13,
            0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3,
            0x2, 0x8, 0x1, 0x1, 0xd, 0xc1, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf,
            0x1, 0xc1, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1, 0xc2, 0x6,
            0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x6, 0x1, 0xc, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x6,
            0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x9, 0x12, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3,
            0x1, 0x7, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc2, 0x6, 0x12, 0x2b, 0x81,
            0x4, 0x0, 0x23, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0xa, 0xc2, 0xa, 0x12, 0x2b,
            0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2,
            0x8, 0x1, 0x1, 0xb, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd,
            0xc2, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1, 0xc2, 0xb, 0x16, 0x2b,
            0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11,
            0x0, 0xc3, 0x6, 0x1, 0xc, 0x0, 0x0, 0x11, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11,
            0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13,
            0x2b, 0x81, 0x4, 0x0, 0x22, 0xc3, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc3, 0x6,
            0x13, 0x2b, 0x81, 0x4, 0x0, 0xa, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1,
            0x1, 0x7, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc3, 0xa,
            0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd, 0xc3, 0xa, 0x16, 0x2b, 0x6, 0x1,
            0x4, 0x1, 0xda, 0x47, 0xf, 0x1, 0xc3, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55,
            0x1, 0x5, 0x1, 0xda, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xda, 0x6, 0x1, 0xc, 0x0, 0x0,
            0x11, 0x0, 0xda, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xda, 0x9, 0x13, 0x2a, 0x86,
            0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xda, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xda,
            0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xda, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0xa,
            0xda, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xda, 0xa, 0x13, 0x2b,
            0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xda, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2,
            0x8, 0x1, 0x1, 0xd, 0xda, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1,
            0xda, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1,
        ];

        let ai = AlgorithmInformation::try_from(&data[..]).unwrap();

        assert_eq!(
            ai,
            AlgorithmInformation(vec![
                (Signing, Rsa(RsaAttributes::new(2048, 17, 0))),
                (Signing, Rsa(RsaAttributes::new(3072, 17, 0))),
                (Signing, Rsa(RsaAttributes::new(4096, 17, 0))),
                (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
                (Signing, Ecc(EccAttributes::new(ECDSA, NistP384r1, None))),
                (Signing, Ecc(EccAttributes::new(ECDSA, NistP521r1, None))),
                (Signing, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
                (
                    Signing,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
                ),
                (
                    Signing,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
                ),
                (
                    Signing,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
                ),
                (Signing, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
                (Signing, Ecc(EccAttributes::new(EdDSA, Curve25519, None))),
                (Decryption, Rsa(RsaAttributes::new(2048, 17, 0))),
                (Decryption, Rsa(RsaAttributes::new(3072, 17, 0))),
                (Decryption, Rsa(RsaAttributes::new(4096, 17, 0))),
                (Decryption, Ecc(EccAttributes::new(ECDH, NistP256r1, None))),
                (Decryption, Ecc(EccAttributes::new(ECDH, NistP384r1, None))),
                (Decryption, Ecc(EccAttributes::new(ECDH, NistP521r1, None))),
                (Decryption, Ecc(EccAttributes::new(ECDH, Secp256k1, None))),
                (
                    Decryption,
                    Ecc(EccAttributes::new(ECDH, BrainpoolP256r1, None))
                ),
                (
                    Decryption,
                    Ecc(EccAttributes::new(ECDH, BrainpoolP384r1, None))
                ),
                (
                    Decryption,
                    Ecc(EccAttributes::new(ECDH, BrainpoolP512r1, None))
                ),
                (Decryption, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
                (Decryption, Ecc(EccAttributes::new(EdDSA, Curve25519, None))),
                (Authentication, Rsa(RsaAttributes::new(2048, 17, 0))),
                (Authentication, Rsa(RsaAttributes::new(3072, 17, 0))),
                (Authentication, Rsa(RsaAttributes::new(4096, 17, 0))),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, Secp256k1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(EdDSA, Ed25519, None))
                ),
                (
                    Authentication,
                    Ecc(EccAttributes::new(EdDSA, Curve25519, None))
                ),
                (Attestation, Rsa(RsaAttributes::new(2048, 17, 0))),
                (Attestation, Rsa(RsaAttributes::new(3072, 17, 0))),
                (Attestation, Rsa(RsaAttributes::new(4096, 17, 0))),
                (
                    Attestation,
                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
                ),
                (
                    Attestation,
                    Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
                ),
                (
                    Attestation,
                    Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
                ),
                (Attestation, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
                (
                    Attestation,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
                ),
                (
                    Attestation,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
                ),
                (
                    Attestation,
                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
                ),
                (Attestation, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
                (
                    Attestation,
                    Ecc(EccAttributes::new(EdDSA, Curve25519, None))
                )
            ])
        );
    }
}