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
//! Hax PKCS#8 serializers for test vectors

use super::TestVectorAlgorithm;
use alloc::vec::Vec;

/// PKCS#8 header for a NIST P-256 private key
const P256_PKCS8_HEADER: &[u8] =
    b"\x30\x81\x87\x02\x01\x00\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\
      \x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x04\x6d\x30\x6b\x02\x01\x01\x04\x20";

/// PKCS#8 interstitial part for a NIST P-256 private key
const P256_PKCS8_PUBKEY_PREFIX: &[u8] = b"\xa1\x44\x03\x42\x00\x04";

/// PKCS#8 header for a NIST P-384 private key
const P384_PKCS8_HEADER: &[u8] =
    b"\x30\x81\xb6\x02\x01\x00\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\
      \x05\x2b\x81\x04\x00\x22\x04\x81\x9e\x30\x81\x9b\x02\x01\x01\x04\x30";

/// PKCS#8 interstitial part for a NIST P-384 private key
const P384_PKCS8_PUBKEY_PREFIX: &[u8] = b"\xa1\x64\x03\x62\x00\x04";

/// Serialize test vector as PKCS#8
pub trait ToPkcs8 {
    /// Serialize this test vector as a PKCS#8 document
    fn to_pkcs8(&self, alg: TestVectorAlgorithm) -> Vec<u8>;
}

impl ToPkcs8 for crate::ecdsa::TestVector {
    fn to_pkcs8(&self, alg: TestVectorAlgorithm) -> Vec<u8> {
        // TODO: better serializer than giant hardcoded bytestring literals, like a PKCS#8 library,
        // or at least a less bogus internal PKCS#8 implementation
        let mut pkcs8_document = match alg {
            TestVectorAlgorithm::NistP256 => P256_PKCS8_HEADER,
            TestVectorAlgorithm::NistP384 => P384_PKCS8_HEADER,
            other => panic!("unsupported test vector algorithm: {:?}", other),
        }
        .to_vec();

        pkcs8_document.extend_from_slice(&self.sk);
        pkcs8_document.extend_from_slice(match alg {
            TestVectorAlgorithm::NistP256 => P256_PKCS8_PUBKEY_PREFIX,
            TestVectorAlgorithm::NistP384 => P384_PKCS8_PUBKEY_PREFIX,
            _ => panic!("this shouldn't be!"),
        });
        pkcs8_document.extend_from_slice(&self.pk);

        pkcs8_document
    }
}