openpgp_card/ocard/data/
algo_info.rs

1// SPDX-FileCopyrightText: 2021-2023 Heiko Schaefer <heiko@schaefer.name>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Algorithm Information [Spec section 4.4.3.11]
5
6use std::convert::TryFrom;
7use std::fmt;
8
9use nom::branch::alt;
10use nom::combinator::map;
11use nom::{branch, bytes::complete as bytes, combinator, multi, sequence};
12
13use crate::ocard::algorithm::{AlgorithmAttributes, AlgorithmInformation};
14use crate::ocard::data::{algo_attrs, complete};
15use crate::ocard::tlv;
16use crate::ocard::KeyType;
17
18impl AlgorithmInformation {
19    pub fn for_keytype(&self, kt: KeyType) -> Vec<&AlgorithmAttributes> {
20        self.0
21            .iter()
22            .filter(|(k, _)| *k == kt)
23            .map(|(_, a)| a)
24            .collect()
25    }
26}
27
28impl fmt::Display for AlgorithmInformation {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        for (kt, a) in &self.0 {
31            let kt = match kt {
32                KeyType::Signing => "SIG",
33                KeyType::Decryption => "DEC",
34                KeyType::Authentication => "AUT",
35                KeyType::Attestation => "ATT",
36            };
37            writeln!(f, "{kt}: {a:?} ")?;
38        }
39        Ok(())
40    }
41}
42
43fn key_type(input: &[u8]) -> nom::IResult<&[u8], KeyType> {
44    alt((
45        map(bytes::tag([0xc1]), |_| KeyType::Signing),
46        map(bytes::tag([0xc2]), |_| KeyType::Decryption),
47        map(bytes::tag([0xc3]), |_| KeyType::Authentication),
48        map(bytes::tag([0xda]), |_| KeyType::Attestation),
49    ))(input)
50}
51
52fn unknown(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> {
53    Ok((&[], AlgorithmAttributes::Unknown(input.to_vec())))
54}
55
56fn parse_one(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> {
57    let (input, a) = combinator::map(
58        combinator::flat_map(tlv::length::length, bytes::take),
59        |i| alt((combinator::all_consuming(algo_attrs::parse), unknown))(i),
60    )(input)?;
61
62    Ok((input, a?.1))
63}
64
65fn parse_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
66    multi::many0(sequence::pair(key_type, parse_one))(input)
67}
68
69fn parse_tl_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
70    let (input, (_, _, list)) =
71        sequence::tuple((bytes::tag([0xfa]), tlv::length::length, parse_list))(input)?;
72
73    Ok((input, list))
74}
75
76fn parse(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
77    // Handle two variations of input format:
78    // a) TLV format (e.g. YubiKey 5)
79    // b) Plain list (e.g. Gnuk, FOSS-Store Smartcard 3.4)
80
81    // -- Gnuk: do_alg_info (uint16_t tag, int with_tag)
82
83    branch::alt((
84        combinator::all_consuming(parse_list),
85        combinator::all_consuming(parse_tl_list),
86    ))(input)
87}
88
89impl TryFrom<&[u8]> for AlgorithmInformation {
90    type Error = crate::Error;
91
92    fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
93        Ok(AlgorithmInformation(complete(parse(input))?))
94    }
95}
96
97// test
98
99#[cfg(test)]
100mod test {
101    use std::convert::TryFrom;
102
103    use crate::ocard::algorithm::{
104        AlgorithmAttributes::*, AlgorithmInformation, Curve::*, EccAttributes, RsaAttributes,
105    };
106    use crate::ocard::crypto::EccType::*;
107    use crate::ocard::KeyType::*;
108
109    #[test]
110    fn test_gnuk() {
111        let data = [
112            0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0,
113            0xc1, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b,
114            0x81, 0x4, 0x0, 0xa, 0xc1, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1,
115            0xc2, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc2, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0,
116            0xc2, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc2, 0x6, 0x13, 0x2b,
117            0x81, 0x4, 0x0, 0xa, 0xc2, 0xb, 0x12, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5,
118            0x1, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20,
119            0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13,
120            0x2b, 0x81, 0x4, 0x0, 0xa, 0xc3, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf,
121            0x1,
122        ];
123
124        let ai = AlgorithmInformation::try_from(&data[..]).unwrap();
125
126        assert_eq!(
127            ai,
128            AlgorithmInformation(vec![
129                (Signing, Rsa(RsaAttributes::new(2048, 32, 0))),
130                (Signing, Rsa(RsaAttributes::new(4096, 32, 0))),
131                (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
132                (Signing, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
133                (Signing, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
134                (Decryption, Rsa(RsaAttributes::new(2048, 32, 0))),
135                (Decryption, Rsa(RsaAttributes::new(4096, 32, 0))),
136                (Decryption, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
137                (Decryption, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
138                (Decryption, Ecc(EccAttributes::new(ECDH, Curve25519, None))),
139                (Authentication, Rsa(RsaAttributes::new(2048, 32, 0))),
140                (Authentication, Rsa(RsaAttributes::new(4096, 32, 0))),
141                (
142                    Authentication,
143                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
144                ),
145                (
146                    Authentication,
147                    Ecc(EccAttributes::new(ECDSA, Secp256k1, None))
148                ),
149                (
150                    Authentication,
151                    Ecc(EccAttributes::new(EdDSA, Ed25519, None))
152                )
153            ])
154        );
155    }
156
157    #[test]
158    fn test_opgp_card_34() {
159        let data = [
160            0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x6, 0x1, 0xc, 0x0, 0x0, 0x20, 0x0,
161            0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce,
162            0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc1, 0x6, 0x13,
163            0x2b, 0x81, 0x4, 0x0, 0x23, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1,
164            0x7, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc1, 0xa, 0x13,
165            0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd, 0xc2, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20,
166            0x0, 0xc2, 0x6, 0x1, 0xc, 0x0, 0x0, 0x20, 0x0, 0xc2, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20,
167            0x0, 0xc2, 0x9, 0x12, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc2, 0x6, 0x12,
168            0x2b, 0x81, 0x4, 0x0, 0x22, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc2, 0xa,
169            0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3,
170            0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1,
171            0x1, 0xd, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x6, 0x1, 0xc, 0x0, 0x0,
172            0x20, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86,
173            0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc3,
174            0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8,
175            0x1, 0x1, 0x7, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc3,
176            0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd,
177        ];
178
179        let ai = AlgorithmInformation::try_from(&data[..]).unwrap();
180
181        assert_eq!(
182            ai,
183            AlgorithmInformation(vec![
184                (Signing, Rsa(RsaAttributes::new(2048, 32, 0))),
185                (Signing, Rsa(RsaAttributes::new(3072, 32, 0))),
186                (Signing, Rsa(RsaAttributes::new(4096, 32, 0))),
187                (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
188                (Signing, Ecc(EccAttributes::new(ECDSA, NistP384r1, None))),
189                (Signing, Ecc(EccAttributes::new(ECDSA, NistP521r1, None))),
190                (
191                    Signing,
192                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
193                ),
194                (
195                    Signing,
196                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
197                ),
198                (
199                    Signing,
200                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
201                ),
202                (Decryption, Rsa(RsaAttributes::new(2048, 32, 0))),
203                (Decryption, Rsa(RsaAttributes::new(3072, 32, 0))),
204                (Decryption, Rsa(RsaAttributes::new(4096, 32, 0))),
205                (Decryption, Ecc(EccAttributes::new(ECDH, NistP256r1, None))),
206                (Decryption, Ecc(EccAttributes::new(ECDH, NistP384r1, None))),
207                (Decryption, Ecc(EccAttributes::new(ECDH, NistP521r1, None))),
208                (
209                    Decryption,
210                    Ecc(EccAttributes::new(ECDH, BrainpoolP256r1, None))
211                ),
212                (
213                    Decryption,
214                    Ecc(EccAttributes::new(ECDH, BrainpoolP384r1, None))
215                ),
216                (
217                    Decryption,
218                    Ecc(EccAttributes::new(ECDH, BrainpoolP512r1, None))
219                ),
220                (Authentication, Rsa(RsaAttributes::new(2048, 32, 0))),
221                (Authentication, Rsa(RsaAttributes::new(3072, 32, 0))),
222                (Authentication, Rsa(RsaAttributes::new(4096, 32, 0))),
223                (
224                    Authentication,
225                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
226                ),
227                (
228                    Authentication,
229                    Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
230                ),
231                (
232                    Authentication,
233                    Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
234                ),
235                (
236                    Authentication,
237                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
238                ),
239                (
240                    Authentication,
241                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
242                ),
243                (
244                    Authentication,
245                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
246                )
247            ])
248        );
249    }
250
251    #[test]
252    fn test_yk5() {
253        let data = [
254            0xfa, 0x82, 0x1, 0xe2, 0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xc1, 0x6, 0x1, 0xc,
255            0x0, 0x0, 0x11, 0x0, 0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xc1, 0x9, 0x13, 0x2a,
256            0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22,
257            0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0,
258            0xa, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc1, 0xa, 0x13,
259            0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3,
260            0x2, 0x8, 0x1, 0x1, 0xd, 0xc1, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf,
261            0x1, 0xc1, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1, 0xc2, 0x6,
262            0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x6, 0x1, 0xc, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x6,
263            0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x9, 0x12, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3,
264            0x1, 0x7, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc2, 0x6, 0x12, 0x2b, 0x81,
265            0x4, 0x0, 0x23, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0xa, 0xc2, 0xa, 0x12, 0x2b,
266            0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2,
267            0x8, 0x1, 0x1, 0xb, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd,
268            0xc2, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1, 0xc2, 0xb, 0x16, 0x2b,
269            0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11,
270            0x0, 0xc3, 0x6, 0x1, 0xc, 0x0, 0x0, 0x11, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11,
271            0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13,
272            0x2b, 0x81, 0x4, 0x0, 0x22, 0xc3, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc3, 0x6,
273            0x13, 0x2b, 0x81, 0x4, 0x0, 0xa, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1,
274            0x1, 0x7, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc3, 0xa,
275            0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd, 0xc3, 0xa, 0x16, 0x2b, 0x6, 0x1,
276            0x4, 0x1, 0xda, 0x47, 0xf, 0x1, 0xc3, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55,
277            0x1, 0x5, 0x1, 0xda, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xda, 0x6, 0x1, 0xc, 0x0, 0x0,
278            0x11, 0x0, 0xda, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xda, 0x9, 0x13, 0x2a, 0x86,
279            0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xda, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xda,
280            0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xda, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0xa,
281            0xda, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xda, 0xa, 0x13, 0x2b,
282            0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xda, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2,
283            0x8, 0x1, 0x1, 0xd, 0xda, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1,
284            0xda, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1,
285        ];
286
287        let ai = AlgorithmInformation::try_from(&data[..]).unwrap();
288
289        assert_eq!(
290            ai,
291            AlgorithmInformation(vec![
292                (Signing, Rsa(RsaAttributes::new(2048, 17, 0))),
293                (Signing, Rsa(RsaAttributes::new(3072, 17, 0))),
294                (Signing, Rsa(RsaAttributes::new(4096, 17, 0))),
295                (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
296                (Signing, Ecc(EccAttributes::new(ECDSA, NistP384r1, None))),
297                (Signing, Ecc(EccAttributes::new(ECDSA, NistP521r1, None))),
298                (Signing, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
299                (
300                    Signing,
301                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
302                ),
303                (
304                    Signing,
305                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
306                ),
307                (
308                    Signing,
309                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
310                ),
311                (Signing, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
312                (Signing, Ecc(EccAttributes::new(EdDSA, Curve25519, None))),
313                (Decryption, Rsa(RsaAttributes::new(2048, 17, 0))),
314                (Decryption, Rsa(RsaAttributes::new(3072, 17, 0))),
315                (Decryption, Rsa(RsaAttributes::new(4096, 17, 0))),
316                (Decryption, Ecc(EccAttributes::new(ECDH, NistP256r1, None))),
317                (Decryption, Ecc(EccAttributes::new(ECDH, NistP384r1, None))),
318                (Decryption, Ecc(EccAttributes::new(ECDH, NistP521r1, None))),
319                (Decryption, Ecc(EccAttributes::new(ECDH, Secp256k1, None))),
320                (
321                    Decryption,
322                    Ecc(EccAttributes::new(ECDH, BrainpoolP256r1, None))
323                ),
324                (
325                    Decryption,
326                    Ecc(EccAttributes::new(ECDH, BrainpoolP384r1, None))
327                ),
328                (
329                    Decryption,
330                    Ecc(EccAttributes::new(ECDH, BrainpoolP512r1, None))
331                ),
332                (Decryption, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
333                (Decryption, Ecc(EccAttributes::new(EdDSA, Curve25519, None))),
334                (Authentication, Rsa(RsaAttributes::new(2048, 17, 0))),
335                (Authentication, Rsa(RsaAttributes::new(3072, 17, 0))),
336                (Authentication, Rsa(RsaAttributes::new(4096, 17, 0))),
337                (
338                    Authentication,
339                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
340                ),
341                (
342                    Authentication,
343                    Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
344                ),
345                (
346                    Authentication,
347                    Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
348                ),
349                (
350                    Authentication,
351                    Ecc(EccAttributes::new(ECDSA, Secp256k1, None))
352                ),
353                (
354                    Authentication,
355                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
356                ),
357                (
358                    Authentication,
359                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
360                ),
361                (
362                    Authentication,
363                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
364                ),
365                (
366                    Authentication,
367                    Ecc(EccAttributes::new(EdDSA, Ed25519, None))
368                ),
369                (
370                    Authentication,
371                    Ecc(EccAttributes::new(EdDSA, Curve25519, None))
372                ),
373                (Attestation, Rsa(RsaAttributes::new(2048, 17, 0))),
374                (Attestation, Rsa(RsaAttributes::new(3072, 17, 0))),
375                (Attestation, Rsa(RsaAttributes::new(4096, 17, 0))),
376                (
377                    Attestation,
378                    Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
379                ),
380                (
381                    Attestation,
382                    Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
383                ),
384                (
385                    Attestation,
386                    Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
387                ),
388                (Attestation, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
389                (
390                    Attestation,
391                    Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
392                ),
393                (
394                    Attestation,
395                    Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
396                ),
397                (
398                    Attestation,
399                    Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
400                ),
401                (Attestation, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
402                (
403                    Attestation,
404                    Ecc(EccAttributes::new(EdDSA, Curve25519, None))
405                )
406            ])
407        );
408    }
409}