|
| 1 | +// Copyright 2022 Contributors to the Parsec project. |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +mod public_rsa_test { |
| 5 | + use picky_asn1::wrapper::IntegerAsn1; |
| 6 | + use picky_asn1_x509::{AlgorithmIdentifier, PublicKey, SubjectPublicKeyInfo}; |
| 7 | + use std::convert::TryFrom; |
| 8 | + use tss_esapi::{ |
| 9 | + abstraction::public::DecodedKey, |
| 10 | + attributes::ObjectAttributesBuilder, |
| 11 | + interface_types::{ |
| 12 | + algorithm::{HashingAlgorithm, PublicAlgorithm, RsaSchemeAlgorithm}, |
| 13 | + key_bits::RsaKeyBits, |
| 14 | + }, |
| 15 | + structures::{Public, PublicBuilder, PublicKeyRsa, PublicRsaParametersBuilder, RsaScheme}, |
| 16 | + }; |
| 17 | + |
| 18 | + const RSA_KEY: [u8; 256] = [ |
| 19 | + 0xc9, 0x75, 0xf8, 0xb2, 0x30, 0xf4, 0x24, 0x6e, 0x95, 0xb1, 0x3c, 0x55, 0x0f, 0xe4, 0x48, |
| 20 | + 0xe9, 0xac, 0x06, 0x1f, 0xa8, 0xbe, 0xa4, 0xd7, 0x1c, 0xa5, 0x5e, 0x2a, 0xbf, 0x60, 0xc2, |
| 21 | + 0x98, 0x63, 0x6c, 0xb4, 0xe2, 0x61, 0x54, 0x31, 0xc3, 0x3e, 0x9d, 0x1a, 0x83, 0x84, 0x18, |
| 22 | + 0x51, 0xe9, 0x8c, 0x24, 0xcf, 0xac, 0xc6, 0x0d, 0x26, 0x2c, 0x9f, 0x2b, 0xd5, 0x91, 0x98, |
| 23 | + 0x89, 0xe3, 0x68, 0x97, 0x36, 0x02, 0xec, 0x16, 0x37, 0x24, 0x08, 0xb4, 0x77, 0xd1, 0x56, |
| 24 | + 0x10, 0x3e, 0xf0, 0x64, 0xf6, 0x68, 0x50, 0x68, 0x31, 0xf8, 0x9b, 0x88, 0xf2, 0xc5, 0xfb, |
| 25 | + 0xc9, 0x21, 0xd2, 0xdf, 0x93, 0x6f, 0x98, 0x94, 0x53, 0x68, 0xe5, 0x25, 0x8d, 0x8a, 0xf1, |
| 26 | + 0xd7, 0x5b, 0xf3, 0xf9, 0xdf, 0x8c, 0x77, 0x24, 0x9e, 0x28, 0x09, 0x36, 0xf0, 0xa2, 0x93, |
| 27 | + 0x17, 0xad, 0xbb, 0x1a, 0xd7, 0x6f, 0x25, 0x6b, 0x0c, 0xd3, 0x76, 0x7f, 0xcf, 0x3a, 0xe3, |
| 28 | + 0x1a, 0x84, 0x57, 0x62, 0x71, 0x8a, 0x6a, 0x42, 0x94, 0x71, 0x21, 0x6a, 0x13, 0x73, 0x17, |
| 29 | + 0x56, 0xa2, 0x38, 0xc1, 0x5e, 0x76, 0x0b, 0x67, 0x6b, 0x6e, 0xcd, 0xd3, 0xe2, 0x8a, 0x80, |
| 30 | + 0x61, 0x6c, 0x1c, 0x60, 0x9d, 0x65, 0xbd, 0x5a, 0x4e, 0xeb, 0xa2, 0x06, 0xd6, 0xbe, 0xf5, |
| 31 | + 0x49, 0xc1, 0x7d, 0xd9, 0x46, 0x3e, 0x9f, 0x2f, 0x92, 0xa4, 0x1a, 0x14, 0x2c, 0x1e, 0xb7, |
| 32 | + 0x6d, 0x71, 0x29, 0x92, 0x43, 0x7b, 0x76, 0xa4, 0x8b, 0x33, 0xf3, 0xd0, 0xda, 0x7c, 0x7f, |
| 33 | + 0x73, 0x50, 0xe2, 0xc5, 0x30, 0xad, 0x9e, 0x0f, 0x61, 0x73, 0xa0, 0xbb, 0x87, 0x1f, 0x0b, |
| 34 | + 0x70, 0xa9, 0xa6, 0xaa, 0x31, 0x2d, 0x62, 0x2c, 0xaf, 0xea, 0x49, 0xb2, 0xce, 0x6c, 0x23, |
| 35 | + 0x90, 0xdd, 0x29, 0x37, 0x67, 0xb1, 0xc9, 0x99, 0x3a, 0x3f, 0xa6, 0x69, 0xc9, 0x0d, 0x24, |
| 36 | + 0x3f, |
| 37 | + ]; |
| 38 | + |
| 39 | + pub fn get_ext_rsa_pub() -> Public { |
| 40 | + let object_attributes = ObjectAttributesBuilder::new() |
| 41 | + .with_user_with_auth(true) |
| 42 | + .with_decrypt(false) |
| 43 | + .with_sign_encrypt(true) |
| 44 | + .with_restricted(false) |
| 45 | + .build() |
| 46 | + .expect("Failed to build object attributes"); |
| 47 | + |
| 48 | + PublicBuilder::new() |
| 49 | + .with_public_algorithm(PublicAlgorithm::Rsa) |
| 50 | + .with_name_hashing_algorithm(HashingAlgorithm::Sha256) |
| 51 | + .with_object_attributes(object_attributes) |
| 52 | + .with_rsa_parameters( |
| 53 | + PublicRsaParametersBuilder::new_unrestricted_signing_key( |
| 54 | + RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256)) |
| 55 | + .expect("Failed to create rsa scheme"), |
| 56 | + RsaKeyBits::Rsa2048, |
| 57 | + Default::default(), // Default exponent is 0 but TPM internally this is mapped to 65537 |
| 58 | + ) |
| 59 | + .build() |
| 60 | + .expect("Failed to create rsa parameters for public structure"), |
| 61 | + ) |
| 62 | + .with_rsa_unique_identifier( |
| 63 | + PublicKeyRsa::try_from(&RSA_KEY[..]) |
| 64 | + .expect("Failed to create Public RSA key from buffer"), |
| 65 | + ) |
| 66 | + .build() |
| 67 | + .expect("Failed to build Public structure") |
| 68 | + } |
| 69 | + |
| 70 | + #[test] |
| 71 | + fn test_public_to_decoded_key_rsa() { |
| 72 | + let public_rsa = get_ext_rsa_pub(); |
| 73 | + let default_exponent = IntegerAsn1::from_bytes_be_signed(65537_u32.to_be_bytes().to_vec()); |
| 74 | + let decoded_key = DecodedKey::try_from(public_rsa) |
| 75 | + .expect("Failed to convert Public structure to DecodedKey (RSA)."); |
| 76 | + match decoded_key { |
| 77 | + DecodedKey::RsaPublicKey(key) => { |
| 78 | + assert_eq!( |
| 79 | + key.public_exponent, default_exponent, |
| 80 | + "RSA exponents are not equal." |
| 81 | + ); |
| 82 | + assert_eq!(key.modulus.as_unsigned_bytes_be(), RSA_KEY); |
| 83 | + } |
| 84 | + DecodedKey::EcPoint(..) => panic!("RSA key was decoded to EcPoint!"), |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + #[test] |
| 89 | + fn test_public_to_subject_public_key_info_rsa() { |
| 90 | + let public_rsa = get_ext_rsa_pub(); |
| 91 | + let default_exponent = IntegerAsn1::from_bytes_be_signed(65537_u32.to_be_bytes().to_vec()); |
| 92 | + let key = SubjectPublicKeyInfo::try_from(public_rsa) |
| 93 | + .expect("Failed to convert Public structure to SubjectPublicKeyInfo (RSA)."); |
| 94 | + assert_eq!(key.algorithm, AlgorithmIdentifier::new_rsa_encryption()); |
| 95 | + match key.subject_public_key { |
| 96 | + PublicKey::Rsa(key) => { |
| 97 | + assert_eq!(key.public_exponent, default_exponent); |
| 98 | + assert_eq!(key.modulus.as_unsigned_bytes_be(), RSA_KEY) |
| 99 | + } |
| 100 | + _ => panic!("PublicKey of SubjectPublicKeyInfo is not an instance for RSA"), |
| 101 | + } |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +mod public_ecc_test { |
| 106 | + use picky_asn1::bit_string::BitString; |
| 107 | + use picky_asn1_x509::{AlgorithmIdentifier, EcParameters, PublicKey, SubjectPublicKeyInfo}; |
| 108 | + use std::convert::TryFrom; |
| 109 | + use tss_esapi::{ |
| 110 | + abstraction::public::DecodedKey, |
| 111 | + attributes::ObjectAttributesBuilder, |
| 112 | + interface_types::{ |
| 113 | + algorithm::{HashingAlgorithm, PublicAlgorithm}, |
| 114 | + ecc::EccCurve, |
| 115 | + }, |
| 116 | + structures::{ |
| 117 | + EccParameter, EccPoint, EccScheme, KeyDerivationFunctionScheme, Public, PublicBuilder, |
| 118 | + PublicEccParametersBuilder, |
| 119 | + }, |
| 120 | + }; |
| 121 | + |
| 122 | + const EC_POINT: [u8; 65] = [ |
| 123 | + 0x04, 0x14, 0xd8, 0x59, 0xec, 0x31, 0xe5, 0x94, 0x0f, 0x2b, 0x3a, 0x08, 0x97, 0x64, 0xc4, |
| 124 | + 0xfb, 0xa6, 0xcd, 0xaf, 0x0e, 0xa2, 0x44, 0x7f, 0x30, 0xcf, 0xe8, 0x2e, 0xe5, 0x1b, 0x47, |
| 125 | + 0x70, 0x01, 0xc3, 0xd6, 0xb4, 0x69, 0x7e, 0xa1, 0xcf, 0x03, 0xdb, 0x05, 0x9c, 0x62, 0x3e, |
| 126 | + 0xc6, 0x15, 0x4f, 0xed, 0xab, 0xa0, 0xa0, 0xab, 0x84, 0x2e, 0x67, 0x0c, 0x98, 0xc7, 0x1e, |
| 127 | + 0xef, 0xd2, 0x51, 0x91, 0xce, |
| 128 | + ]; |
| 129 | + |
| 130 | + pub fn get_ecc_point() -> EccPoint { |
| 131 | + let x = |
| 132 | + EccParameter::try_from(&EC_POINT[1..33]).expect("Failed to construct x EccParameter"); |
| 133 | + let y: EccParameter = |
| 134 | + EccParameter::try_from(&EC_POINT[33..]).expect("Failed to construct y EccParameter"); |
| 135 | + EccPoint::new(x, y) |
| 136 | + } |
| 137 | + |
| 138 | + pub fn get_ext_ecc_pub() -> Public { |
| 139 | + let object_attributes = ObjectAttributesBuilder::new() |
| 140 | + .with_user_with_auth(true) |
| 141 | + .with_decrypt(false) |
| 142 | + .with_sign_encrypt(true) |
| 143 | + .with_restricted(false) |
| 144 | + .build() |
| 145 | + .expect("Failed to build object attributes"); |
| 146 | + |
| 147 | + let ecc_parameters = PublicEccParametersBuilder::new() |
| 148 | + .with_ecc_scheme(EccScheme::Null) |
| 149 | + .with_curve(EccCurve::NistP256) |
| 150 | + .with_is_signing_key(false) |
| 151 | + .with_is_decryption_key(true) |
| 152 | + .with_restricted(false) |
| 153 | + .with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null) |
| 154 | + .build() |
| 155 | + .expect("Failed to build PublicEccParameters"); |
| 156 | + PublicBuilder::new() |
| 157 | + .with_public_algorithm(PublicAlgorithm::Ecc) |
| 158 | + .with_name_hashing_algorithm(HashingAlgorithm::Sha256) |
| 159 | + .with_object_attributes(object_attributes) |
| 160 | + .with_ecc_parameters(ecc_parameters) |
| 161 | + .with_ecc_unique_identifier(get_ecc_point()) |
| 162 | + .build() |
| 163 | + .expect("Failed to build Public structure") |
| 164 | + } |
| 165 | + |
| 166 | + #[test] |
| 167 | + fn test_public_to_decoded_key_ecc() { |
| 168 | + let public_ecc = get_ext_ecc_pub(); |
| 169 | + let decoded_key = DecodedKey::try_from(public_ecc) |
| 170 | + .expect("Failed to convert Public structure to DecodedKey (ECC)."); |
| 171 | + |
| 172 | + match decoded_key { |
| 173 | + DecodedKey::RsaPublicKey(..) => panic!("ECC key was decoded to RsaPublicKey!"), |
| 174 | + DecodedKey::EcPoint(ec_point) => { |
| 175 | + assert_eq!(ec_point.to_vec(), EC_POINT.to_vec()); |
| 176 | + } |
| 177 | + } |
| 178 | + } |
| 179 | + |
| 180 | + #[test] |
| 181 | + fn test_public_to_subject_public_key_info_ecc() { |
| 182 | + let public_ecc = get_ext_ecc_pub(); |
| 183 | + let key = SubjectPublicKeyInfo::try_from(public_ecc) |
| 184 | + .expect("Failed to convert Public structure to SubjectPublicKeyInfo (ECC)."); |
| 185 | + assert_eq!( |
| 186 | + key.algorithm, |
| 187 | + AlgorithmIdentifier::new_elliptic_curve(EcParameters::NamedCurve( |
| 188 | + picky_asn1_x509::oids::secp256r1().into() |
| 189 | + )) |
| 190 | + ); |
| 191 | + match key.subject_public_key { |
| 192 | + PublicKey::Ec(ec_point) => { |
| 193 | + let ec_point_bitstring: BitString = ec_point.into(); |
| 194 | + let ec_point_vec: Vec<u8> = ec_point_bitstring.into(); |
| 195 | + assert_eq!(ec_point_vec, EC_POINT.to_vec()); |
| 196 | + } |
| 197 | + _ => panic!("PublicKey of SubjectPublicKeyInfo is not an instance for ECC"), |
| 198 | + } |
| 199 | + } |
| 200 | +} |
0 commit comments