|
@@ -281,26 +281,55 @@ impl Cookie {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-#[derive(Serialize, Deserialize, Clone)]
|
|
|
|
-struct StoredKeyPair {
|
|
|
|
- public: AsymKeyPub,
|
|
|
|
|
|
+#[derive(Serialize, Clone)]
|
|
|
|
+struct StoredKeyPair<S: Scheme> {
|
|
|
|
+ public: AsymKeyPub<S>,
|
|
private: TPM2_HANDLE,
|
|
private: TPM2_HANDLE,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+impl<'de, S: Scheme> Deserialize<'de> for StoredKeyPair<S> {
|
|
|
|
+ fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
|
|
|
|
+ const FIELDS: &[&str] = &["public", "private"];
|
|
|
|
+
|
|
|
|
+ struct StructVisitor<S: Scheme>(PhantomData<S>);
|
|
|
|
+
|
|
|
|
+ impl<'de, S: Scheme> Visitor<'de> for StructVisitor<S> {
|
|
|
|
+ type Value = StoredKeyPair<S>;
|
|
|
|
+
|
|
|
|
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
+ formatter.write_fmt(format_args!("struct {}", stringify!(StoredKeyPair)))
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn visit_seq<A: SeqAccess<'de>>(
|
|
|
|
+ self, mut seq: A
|
|
|
|
+ ) -> std::result::Result<Self::Value, A::Error> {
|
|
|
|
+ let public : AsymKeyPub<S> = seq.next_element()?
|
|
|
|
+ .ok_or_else(|| de::Error::missing_field(FIELDS[0]))?;
|
|
|
|
+ let private: TPM2_HANDLE = seq.next_element()?
|
|
|
|
+ .ok_or_else(|| de::Error::missing_field(FIELDS[1]))?;
|
|
|
|
+ let pair = StoredKeyPair { public, private };
|
|
|
|
+ Ok(pair)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ d.deserialize_struct(stringify!(StoredKeyPair), FIELDS, StructVisitor(PhantomData))
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
struct TpmHandles {
|
|
struct TpmHandles {
|
|
- sign: StoredKeyPair,
|
|
|
|
- enc: StoredKeyPair,
|
|
|
|
|
|
+ sign: StoredKeyPair<Sign>,
|
|
|
|
+ enc: StoredKeyPair<Encrypt>,
|
|
}
|
|
}
|
|
|
|
|
|
impl TpmHandles {
|
|
impl TpmHandles {
|
|
- fn new(sign: StoredKeyPair, enc: StoredKeyPair) -> TpmHandles {
|
|
|
|
|
|
+ fn new(sign: StoredKeyPair<Sign>, enc: StoredKeyPair<Encrypt>) -> TpmHandles {
|
|
TpmHandles { sign, enc }
|
|
TpmHandles { sign, enc }
|
|
}
|
|
}
|
|
|
|
|
|
fn to_key_handles(&self, context: &mut Context) -> Result<KeyHandles> {
|
|
fn to_key_handles(&self, context: &mut Context) -> Result<KeyHandles> {
|
|
- let sign = SignKey(KeyPair::from_stored(context, &self.sign)?);
|
|
|
|
- let enc = EncKey(KeyPair::from_stored(context, &self.enc)?);
|
|
|
|
|
|
+ let sign = KeyPair::from_stored(context, &self.sign)?;
|
|
|
|
+ let enc = KeyPair::from_stored(context, &self.enc)?;
|
|
Ok(KeyHandles {sign, enc})
|
|
Ok(KeyHandles {sign, enc})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -384,58 +413,57 @@ impl KeyKind {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-struct KeyParams<'a> {
|
|
|
|
- kind: KeyKind,
|
|
|
|
|
|
+impl TryInto<RsaScheme> for SchemeKind {
|
|
|
|
+ type Error = Error;
|
|
|
|
+ fn try_into(self) -> Result<RsaScheme> {
|
|
|
|
+ match self {
|
|
|
|
+ SchemeKind::Sign(sign) => match sign {
|
|
|
|
+ Sign::RsaSsaPss(_)
|
|
|
|
+ => Ok(RsaScheme::RsaPss(HashScheme::new(HashingAlgorithm::Sha256))),
|
|
|
|
+ },
|
|
|
|
+ SchemeKind::Encrypt(encrypt) => match encrypt {
|
|
|
|
+ Encrypt::RsaEsOaep(_)
|
|
|
|
+ => Ok(RsaScheme::Oaep(HashScheme::new(HashingAlgorithm::Sha256))),
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+struct KeyBuilder<'a, S: Scheme> {
|
|
|
|
+ scheme: S,
|
|
allow_dup: bool,
|
|
allow_dup: bool,
|
|
- scheme: RsaScheme,
|
|
|
|
unique: &'a [u8],
|
|
unique: &'a [u8],
|
|
auth: Option<Auth>,
|
|
auth: Option<Auth>,
|
|
}
|
|
}
|
|
|
|
|
|
-impl<'a> KeyParams<'a> {
|
|
|
|
|
|
+impl<'a, S: Scheme> KeyBuilder<'a, S> {
|
|
/// The public exponent to use for generated RSA keys.
|
|
/// The public exponent to use for generated RSA keys.
|
|
const RSA_EXPONENT: u32 = 65537; // 2**16 + 1
|
|
const RSA_EXPONENT: u32 = 65537; // 2**16 + 1
|
|
|
|
|
|
const RSA_KEY_BITS: RsaKeyBits = RsaKeyBits::Rsa3072;
|
|
const RSA_KEY_BITS: RsaKeyBits = RsaKeyBits::Rsa3072;
|
|
|
|
|
|
- fn with_unique(unique: &'a [u8]) -> KeyParams<'a> {
|
|
|
|
- KeyParams {
|
|
|
|
- kind: KeyKind::Sign,
|
|
|
|
|
|
+ fn new(scheme: S, unique: &'a [u8]) -> KeyBuilder<'a, S> {
|
|
|
|
+ KeyBuilder {
|
|
|
|
+ scheme,
|
|
allow_dup: false,
|
|
allow_dup: false,
|
|
- scheme: RsaScheme::Null,
|
|
|
|
unique,
|
|
unique,
|
|
auth: None,
|
|
auth: None,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- fn with_kind(mut self, kind: KeyKind) -> Self {
|
|
|
|
- self.kind = kind;
|
|
|
|
- self
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fn with_allow_dup(mut self, allow_dup: bool) -> Self {
|
|
|
|
- self.allow_dup = allow_dup;
|
|
|
|
- self
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fn with_scheme(mut self, scheme: RsaScheme) -> Self {
|
|
|
|
- self.scheme = scheme;
|
|
|
|
- self
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fn with_auth(mut self, auth: Auth) -> Self {
|
|
|
|
- self.auth = Some(auth);
|
|
|
|
- self
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
fn template(&self) -> Result<Public> {
|
|
fn template(&self) -> Result<Public> {
|
|
|
|
+ let scheme_enum = self.scheme.as_enum();
|
|
|
|
+ let decrypt = match scheme_enum {
|
|
|
|
+ SchemeKind::Sign(_) => false,
|
|
|
|
+ SchemeKind::Encrypt(_) => true,
|
|
|
|
+ };
|
|
let object_attributes = ObjectAttributes::builder()
|
|
let object_attributes = ObjectAttributes::builder()
|
|
.with_fixed_tpm(!self.allow_dup)
|
|
.with_fixed_tpm(!self.allow_dup)
|
|
.with_fixed_parent(!self.allow_dup)
|
|
.with_fixed_parent(!self.allow_dup)
|
|
.with_sensitive_data_origin(true)
|
|
.with_sensitive_data_origin(true)
|
|
.with_user_with_auth(true)
|
|
.with_user_with_auth(true)
|
|
- .with_decrypt(self.kind.decrypt())
|
|
|
|
- .with_sign_encrypt(self.kind.sign())
|
|
|
|
|
|
+ .with_decrypt(decrypt)
|
|
|
|
+ .with_sign_encrypt(!decrypt)
|
|
.with_restricted(false)
|
|
.with_restricted(false)
|
|
.build()
|
|
.build()
|
|
.conv_err()?;
|
|
.conv_err()?;
|
|
@@ -443,7 +471,7 @@ impl<'a> KeyParams<'a> {
|
|
let auth_policy = Digest::empty();
|
|
let auth_policy = Digest::empty();
|
|
let parameters = PublicRsaParameters::new(
|
|
let parameters = PublicRsaParameters::new(
|
|
SymmetricDefinitionObject::Null,
|
|
SymmetricDefinitionObject::Null,
|
|
- self.scheme,
|
|
|
|
|
|
+ scheme_enum.try_into()?,
|
|
Self::RSA_KEY_BITS,
|
|
Self::RSA_KEY_BITS,
|
|
RsaExponent::try_from(Self::RSA_EXPONENT).conv_err()?,
|
|
RsaExponent::try_from(Self::RSA_EXPONENT).conv_err()?,
|
|
);
|
|
);
|
|
@@ -458,57 +486,41 @@ impl<'a> KeyParams<'a> {
|
|
};
|
|
};
|
|
Ok(public)
|
|
Ok(public)
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ fn with_allow_dup(mut self, allow_dup: bool) -> Self {
|
|
|
|
+ self.allow_dup = allow_dup;
|
|
|
|
+ self
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn with_auth(mut self, auth: Auth) -> Self {
|
|
|
|
+ self.auth = Some(auth);
|
|
|
|
+ self
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
#[derive(Clone)]
|
|
#[derive(Clone)]
|
|
-struct KeyPair {
|
|
|
|
- public: AsymKeyPub,
|
|
|
|
|
|
+struct KeyPair<S: Scheme> {
|
|
|
|
+ public: AsymKeyPub<S>,
|
|
/// A rust struct which wraps an `ESYS_TR` from the ESAPI.
|
|
/// A rust struct which wraps an `ESYS_TR` from the ESAPI.
|
|
private: KeyHandle
|
|
private: KeyHandle
|
|
}
|
|
}
|
|
|
|
|
|
-impl KeyPair {
|
|
|
|
- fn from_stored(context: &mut Context, stored: &StoredKeyPair) -> Result<KeyPair> {
|
|
|
|
|
|
+impl<S: Scheme> KeyPair<S> {
|
|
|
|
+ fn from_stored(context: &mut Context, stored: &StoredKeyPair<S>) -> Result<KeyPair<S>> {
|
|
let tpm_handle = TpmHandle::try_from(stored.private).conv_err()?;
|
|
let tpm_handle = TpmHandle::try_from(stored.private).conv_err()?;
|
|
let key_handle = context.key_handle(tpm_handle)?;
|
|
let key_handle = context.key_handle(tpm_handle)?;
|
|
Ok(KeyPair { public: stored.public.clone(), private: key_handle })
|
|
Ok(KeyPair { public: stored.public.clone(), private: key_handle })
|
|
}
|
|
}
|
|
|
|
|
|
- fn to_stored(&self, private: TPM2_HANDLE) -> StoredKeyPair {
|
|
|
|
|
|
+ fn to_stored(&self, private: TPM2_HANDLE) -> StoredKeyPair<S> {
|
|
let public = self.public.clone();
|
|
let public = self.public.clone();
|
|
StoredKeyPair { public, private }
|
|
StoredKeyPair { public, private }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-#[derive(Clone)]
|
|
|
|
-struct SignKey(KeyPair);
|
|
|
|
-
|
|
|
|
-impl SignKey {
|
|
|
|
- fn public(&self) -> &AsymKeyPub {
|
|
|
|
- &self.0.public
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fn private(&self) -> KeyHandle {
|
|
|
|
- self.0.private
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#[derive(Clone)]
|
|
|
|
-struct EncKey(KeyPair);
|
|
|
|
-
|
|
|
|
-impl EncKey {
|
|
|
|
- fn public(&self) -> &AsymKeyPub {
|
|
|
|
- &self.0.public
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fn private(&self) -> KeyHandle {
|
|
|
|
- self.0.private
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
struct KeyHandles {
|
|
struct KeyHandles {
|
|
- sign: SignKey,
|
|
|
|
- enc: EncKey,
|
|
|
|
|
|
+ sign: KeyPair<Sign>,
|
|
|
|
+ enc: KeyPair<Encrypt>,
|
|
}
|
|
}
|
|
|
|
|
|
struct State {
|
|
struct State {
|
|
@@ -529,8 +541,8 @@ impl State {
|
|
};
|
|
};
|
|
let key_handles = tpm_handles.to_key_handles(&mut self.context)?;
|
|
let key_handles = tpm_handles.to_key_handles(&mut self.context)?;
|
|
let auth = self.storage.cookie.auth();
|
|
let auth = self.storage.cookie.auth();
|
|
- self.context.tr_set_auth(key_handles.enc.private().into(), auth.clone())?;
|
|
|
|
- self.context.tr_set_auth(key_handles.sign.private().into(), auth)?;
|
|
|
|
|
|
+ self.context.tr_set_auth(key_handles.enc.private.into(), auth.clone())?;
|
|
|
|
+ self.context.tr_set_auth(key_handles.sign.private.into(), auth)?;
|
|
self.node_creds = Some(TpmCreds::new(key_handles, state));
|
|
self.node_creds = Some(TpmCreds::new(key_handles, state));
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
@@ -564,7 +576,7 @@ impl TpmCredStore {
|
|
Ok(())
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
|
|
- fn gen_key(&self, params: KeyParams) -> Result<KeyPair> {
|
|
|
|
|
|
+ fn gen_key<S: Scheme>(&self, params: KeyBuilder<S>) -> Result<KeyPair<S>> {
|
|
let result = {
|
|
let result = {
|
|
let mut guard = self.state.write().conv_err()?;
|
|
let mut guard = self.state.write().conv_err()?;
|
|
guard.context.create_primary(
|
|
guard.context.create_primary(
|
|
@@ -577,52 +589,48 @@ impl TpmCredStore {
|
|
)
|
|
)
|
|
.conv_err()?
|
|
.conv_err()?
|
|
};
|
|
};
|
|
- let public = AsymKeyPub::try_from(result.out_public)?;
|
|
|
|
|
|
+ let public = AsymKeyPub::try_from(result.out_public, params.scheme)?;
|
|
Ok(KeyPair { public, private: result.key_handle })
|
|
Ok(KeyPair { public, private: result.key_handle })
|
|
}
|
|
}
|
|
|
|
|
|
- fn gen_node_sign_key(&self) -> Result<SignKey> {
|
|
|
|
- let params = KeyParams::with_unique(self.cookie.as_slice())
|
|
|
|
|
|
+ fn gen_node_sign_key(&self) -> Result<KeyPair<Sign>> {
|
|
|
|
+ let params = KeyBuilder::new(Sign::RSA_PSS_3072_SHA_256, self.cookie.as_slice())
|
|
.with_allow_dup(false)
|
|
.with_allow_dup(false)
|
|
- .with_kind(KeyKind::Sign)
|
|
|
|
- .with_scheme(RsaScheme::Null)
|
|
|
|
.with_auth(self.cookie.auth());
|
|
.with_auth(self.cookie.auth());
|
|
- Ok(SignKey(self.gen_key(params)?))
|
|
|
|
|
|
+ self.gen_key(params)
|
|
}
|
|
}
|
|
|
|
|
|
- fn gen_node_enc_key(&self) -> Result<EncKey> {
|
|
|
|
- let params = KeyParams::with_unique(self.cookie.as_slice())
|
|
|
|
|
|
+ fn gen_node_enc_key(&self) -> Result<KeyPair<Encrypt>> {
|
|
|
|
+ let params = KeyBuilder::new(Encrypt::RSA_OAEP_3072_SHA_256, self.cookie.as_slice())
|
|
.with_allow_dup(false)
|
|
.with_allow_dup(false)
|
|
- .with_kind(KeyKind::Decrypt)
|
|
|
|
- .with_scheme(RsaScheme::RsaEs)
|
|
|
|
.with_auth(self.cookie.auth());
|
|
.with_auth(self.cookie.auth());
|
|
- Ok(EncKey(self.gen_key(params)?))
|
|
|
|
|
|
+ self.gen_key(params)
|
|
}
|
|
}
|
|
|
|
|
|
fn persist<F: FnOnce(&mut Storage, TpmHandles)>(
|
|
fn persist<F: FnOnce(&mut Storage, TpmHandles)>(
|
|
&self, creds: &TpmCreds, update_storage: F
|
|
&self, creds: &TpmCreds, update_storage: F
|
|
) -> Result<()> {
|
|
) -> Result<()> {
|
|
let mut guard = self.state.write().conv_err()?;
|
|
let mut guard = self.state.write().conv_err()?;
|
|
- let sign_handle = guard.context.persist_key(creds.sign.private())?;
|
|
|
|
- let enc_handle = match guard.context.persist_key(creds.enc.private()) {
|
|
|
|
|
|
+ let sign_handle = guard.context.persist_key(creds.sign.private)?;
|
|
|
|
+ let enc_handle = match guard.context.persist_key(creds.enc.private) {
|
|
Ok(handle) => handle,
|
|
Ok(handle) => handle,
|
|
Err(error) => {
|
|
Err(error) => {
|
|
- guard.context.evict_key(sign_handle, Some(creds.sign.private()))?;
|
|
|
|
|
|
+ guard.context.evict_key(sign_handle, Some(creds.sign.private))?;
|
|
return Err(error)
|
|
return Err(error)
|
|
}
|
|
}
|
|
};
|
|
};
|
|
let handles = TpmHandles::new(
|
|
let handles = TpmHandles::new(
|
|
- creds.sign.0.to_stored(sign_handle),
|
|
|
|
- creds.enc.0.to_stored(enc_handle));
|
|
|
|
|
|
+ creds.sign.to_stored(sign_handle),
|
|
|
|
+ creds.enc.to_stored(enc_handle));
|
|
update_storage(&mut guard.storage, handles);
|
|
update_storage(&mut guard.storage, handles);
|
|
match self.save_storage(&mut guard) {
|
|
match self.save_storage(&mut guard) {
|
|
Ok(_) => Ok(()),
|
|
Ok(_) => Ok(()),
|
|
Err(error) => {
|
|
Err(error) => {
|
|
- let result = guard.context.evict_key(sign_handle, Some(creds.sign.private()));
|
|
|
|
|
|
+ let result = guard.context.evict_key(sign_handle, Some(creds.sign.private));
|
|
if let Err(error) = result {
|
|
if let Err(error) = result {
|
|
error!("failed to evict signing key due to error: {:?}", error)
|
|
error!("failed to evict signing key due to error: {:?}", error)
|
|
}
|
|
}
|
|
- let result = guard.context.evict_key(enc_handle, Some(creds.enc.private()));
|
|
|
|
|
|
+ let result = guard.context.evict_key(enc_handle, Some(creds.enc.private));
|
|
if let Err(error) = result {
|
|
if let Err(error) = result {
|
|
error!("failed to evict encryption key due to error: {:?}", error)
|
|
error!("failed to evict encryption key due to error: {:?}", error)
|
|
}
|
|
}
|
|
@@ -639,24 +647,20 @@ impl TpmCredStore {
|
|
Ok(creds)
|
|
Ok(creds)
|
|
}
|
|
}
|
|
|
|
|
|
- fn gen_root_sign_key(&self, password: &str) -> Result<SignKey> {
|
|
|
|
|
|
+ fn gen_root_sign_key(&self, password: &str) -> Result<KeyPair<Sign>> {
|
|
let unique: [u8; COOKIE_LEN] = rand_array()?;
|
|
let unique: [u8; COOKIE_LEN] = rand_array()?;
|
|
- let params = KeyParams::with_unique(unique.as_slice())
|
|
|
|
|
|
+ let params = KeyBuilder::new(Sign::RSA_PSS_3072_SHA_256, unique.as_slice())
|
|
.with_allow_dup(true)
|
|
.with_allow_dup(true)
|
|
- .with_kind(KeyKind::Sign)
|
|
|
|
- .with_scheme(RsaScheme::Null)
|
|
|
|
.with_auth(Auth::try_from(password.as_bytes()).conv_err()?);
|
|
.with_auth(Auth::try_from(password.as_bytes()).conv_err()?);
|
|
- Ok(SignKey(self.gen_key(params)?))
|
|
|
|
|
|
+ self.gen_key(params)
|
|
}
|
|
}
|
|
|
|
|
|
- fn gen_root_enc_key(&self, password: &str) -> Result<EncKey> {
|
|
|
|
|
|
+ fn gen_root_enc_key(&self, password: &str) -> Result<KeyPair<Encrypt>> {
|
|
let unique: [u8; COOKIE_LEN] = rand_array()?;
|
|
let unique: [u8; COOKIE_LEN] = rand_array()?;
|
|
- let params = KeyParams::with_unique(unique.as_slice())
|
|
|
|
|
|
+ let params = KeyBuilder::new(Encrypt::RSA_OAEP_3072_SHA_256, unique.as_slice())
|
|
.with_allow_dup(true)
|
|
.with_allow_dup(true)
|
|
- .with_kind(KeyKind::Decrypt)
|
|
|
|
- .with_scheme(RsaScheme::RsaEs)
|
|
|
|
.with_auth(Auth::try_from(password.as_bytes()).conv_err()?);
|
|
.with_auth(Auth::try_from(password.as_bytes()).conv_err()?);
|
|
- Ok(EncKey(self.gen_key(params)?))
|
|
|
|
|
|
+ self.gen_key(params)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -683,8 +687,8 @@ impl CredStore for TpmCredStore {
|
|
let mut guard = self.state.write().conv_err()?;
|
|
let mut guard = self.state.write().conv_err()?;
|
|
let key_handles = root_handles.to_key_handles(&mut guard.context)?;
|
|
let key_handles = root_handles.to_key_handles(&mut guard.context)?;
|
|
let auth = Auth::try_from(password.as_bytes()).conv_err()?;
|
|
let auth = Auth::try_from(password.as_bytes()).conv_err()?;
|
|
- guard.context.tr_set_auth(key_handles.sign.private().into(), auth.clone())?;
|
|
|
|
- guard.context.tr_set_auth(key_handles.enc.private().into(), auth)?;
|
|
|
|
|
|
+ guard.context.tr_set_auth(key_handles.sign.private.into(), auth.clone())?;
|
|
|
|
+ guard.context.tr_set_auth(key_handles.enc.private.into(), auth)?;
|
|
Ok(TpmCreds::new(key_handles, &self.state))
|
|
Ok(TpmCreds::new(key_handles, &self.state))
|
|
}
|
|
}
|
|
|
|
|
|
@@ -703,10 +707,8 @@ impl CredStore for TpmCredStore {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-impl TryFrom<Public> for AsymKeyPub {
|
|
|
|
- type Error = Error;
|
|
|
|
-
|
|
|
|
- fn try_from(public: Public) -> Result<AsymKeyPub> {
|
|
|
|
|
|
+impl<S: Scheme> AsymKeyPub<S> {
|
|
|
|
+ fn try_from(public: Public, scheme: S) -> Result<AsymKeyPub<S>> {
|
|
match public {
|
|
match public {
|
|
Public::Rsa { parameters, unique, .. } => {
|
|
Public::Rsa { parameters, unique, .. } => {
|
|
let exponent_value = parameters.exponent().value();
|
|
let exponent_value = parameters.exponent().value();
|
|
@@ -714,7 +716,7 @@ impl TryFrom<Public> for AsymKeyPub {
|
|
let modulus = BigNum::from_slice(unique.as_slice()).conv_err()?;
|
|
let modulus = BigNum::from_slice(unique.as_slice()).conv_err()?;
|
|
let rsa = Rsa::from_public_components(modulus, exponent).conv_err()?;
|
|
let rsa = Rsa::from_public_components(modulus, exponent).conv_err()?;
|
|
let pkey = PKey::from_rsa(rsa).conv_err()?;
|
|
let pkey = PKey::from_rsa(rsa).conv_err()?;
|
|
- Ok(AsymKeyPub { pkey, kind: AsymKeyKind::Rsa })
|
|
|
|
|
|
+ Ok(AsymKeyPub { pkey, scheme })
|
|
},
|
|
},
|
|
_ => Err(Error::custom("Unsupported key type returned by TPM")),
|
|
_ => Err(Error::custom("Unsupported key type returned by TPM")),
|
|
}
|
|
}
|
|
@@ -797,8 +799,8 @@ impl HashcheckTicketExt for HashcheckTicket {
|
|
#[derive(Clone)]
|
|
#[derive(Clone)]
|
|
pub(crate) struct TpmCreds {
|
|
pub(crate) struct TpmCreds {
|
|
state: Arc<RwLock<State>>,
|
|
state: Arc<RwLock<State>>,
|
|
- sign: SignKey,
|
|
|
|
- enc: EncKey,
|
|
|
|
|
|
+ sign: KeyPair<Sign>,
|
|
|
|
+ enc: KeyPair<Encrypt>,
|
|
}
|
|
}
|
|
|
|
|
|
impl TpmCreds {
|
|
impl TpmCreds {
|
|
@@ -811,8 +813,8 @@ impl Owned for TpmCreds {
|
|
fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
fn owner_of_kind(&self, kind: HashKind) -> Principal {
|
|
fn hash(creds: &TpmCreds, msg_digest: MessageDigest, mut buf: &mut [u8]) {
|
|
fn hash(creds: &TpmCreds, msg_digest: MessageDigest, mut buf: &mut [u8]) {
|
|
let digest = {
|
|
let digest = {
|
|
- let sign_der = creds.sign.public().to_der().unwrap();
|
|
|
|
- let enc_der = creds.enc.public().to_der().unwrap();
|
|
|
|
|
|
+ let sign_der = creds.sign.public.to_der().unwrap();
|
|
|
|
+ let enc_der = creds.enc.public.to_der().unwrap();
|
|
let mut hasher = Hasher::new(msg_digest).unwrap();
|
|
let mut hasher = Hasher::new(msg_digest).unwrap();
|
|
hasher.update(sign_der.as_slice()).unwrap();
|
|
hasher.update(sign_der.as_slice()).unwrap();
|
|
hasher.update(enc_der.as_slice()).unwrap();
|
|
hasher.update(enc_der.as_slice()).unwrap();
|
|
@@ -837,13 +839,13 @@ impl Owned for TpmCreds {
|
|
|
|
|
|
impl Verifier for TpmCreds {
|
|
impl Verifier for TpmCreds {
|
|
fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
fn verify<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I, signature: &[u8]) -> Result<bool> {
|
|
- self.sign.public().verify(parts, signature)
|
|
|
|
|
|
+ self.sign.public.verify(parts, signature)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl Encrypter for TpmCreds {
|
|
impl Encrypter for TpmCreds {
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
- self.enc.public().encrypt(slice)
|
|
|
|
|
|
+ self.enc.public.encrypt(slice)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -851,7 +853,7 @@ impl CredsPub for TpmCreds {}
|
|
|
|
|
|
impl Signer for TpmCreds {
|
|
impl Signer for TpmCreds {
|
|
fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
fn sign<'a, I: Iterator<Item=&'a [u8]>>(&self, parts: I) -> Result<Signature> {
|
|
- let msg_digest = self.sign.public().digest();
|
|
|
|
|
|
+ let msg_digest = self.sign.public.digest();
|
|
let digest = {
|
|
let digest = {
|
|
let mut hasher = Hasher::new(msg_digest).conv_err()?;
|
|
let mut hasher = Hasher::new(msg_digest).conv_err()?;
|
|
for part in parts {
|
|
for part in parts {
|
|
@@ -865,7 +867,7 @@ impl Signer for TpmCreds {
|
|
let scheme = SignatureScheme::RsaSsa { hash_scheme: msg_digest.hash_scheme()? };
|
|
let scheme = SignatureScheme::RsaSsa { hash_scheme: msg_digest.hash_scheme()? };
|
|
let sig = {
|
|
let sig = {
|
|
let mut guard = self.state.write().conv_err()?;
|
|
let mut guard = self.state.write().conv_err()?;
|
|
- guard.context.sign(self.sign.private(), digest, scheme, validation)
|
|
|
|
|
|
+ guard.context.sign(self.sign.private, digest, scheme, validation)
|
|
.conv_err()?
|
|
.conv_err()?
|
|
};
|
|
};
|
|
let buf = match sig {
|
|
let buf = match sig {
|
|
@@ -890,7 +892,7 @@ impl Decrypter for TpmCreds {
|
|
let label = Data::try_from(empty.as_slice()).conv_err()?;
|
|
let label = Data::try_from(empty.as_slice()).conv_err()?;
|
|
let plain_text = {
|
|
let plain_text = {
|
|
let mut guard = self.state.write().conv_err()?;
|
|
let mut guard = self.state.write().conv_err()?;
|
|
- guard.context.rsa_decrypt(self.enc.private(), cipher_text, in_scheme, label)?
|
|
|
|
|
|
+ guard.context.rsa_decrypt(self.enc.private, cipher_text, in_scheme, label)?
|
|
};
|
|
};
|
|
Ok(Vec::from(plain_text.value()))
|
|
Ok(Vec::from(plain_text.value()))
|
|
}
|
|
}
|
|
@@ -899,8 +901,8 @@ impl Decrypter for TpmCreds {
|
|
impl CredsPriv for TpmCreds {}
|
|
impl CredsPriv for TpmCreds {}
|
|
|
|
|
|
impl Creds for TpmCreds {
|
|
impl Creds for TpmCreds {
|
|
- fn public(&self) -> &AsymKeyPub {
|
|
|
|
- unimplemented!()
|
|
|
|
|
|
+ fn public(&self) -> &AsymKeyPub<Sign> {
|
|
|
|
+ &self.sign.public
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1272,7 +1274,7 @@ active_pcr_banks = sha256
|
|
/// Checks that the value of `TpmCredStore::RSA_KEY_BITS` matches the value of `RSA_KEY_BYTES`.
|
|
/// Checks that the value of `TpmCredStore::RSA_KEY_BITS` matches the value of `RSA_KEY_BYTES`.
|
|
#[test]
|
|
#[test]
|
|
fn rsa_key_bits_and_key_bytes_compatible() {
|
|
fn rsa_key_bits_and_key_bytes_compatible() {
|
|
- let bytes = match KeyParams::RSA_KEY_BITS {
|
|
|
|
|
|
+ let bytes = match KeyBuilder::<Sign>::RSA_KEY_BITS {
|
|
RsaKeyBits::Rsa1024 => 128,
|
|
RsaKeyBits::Rsa1024 => 128,
|
|
RsaKeyBits::Rsa2048 => 256,
|
|
RsaKeyBits::Rsa2048 => 256,
|
|
RsaKeyBits::Rsa3072 => 384,
|
|
RsaKeyBits::Rsa3072 => 384,
|
|
@@ -1300,7 +1302,7 @@ active_pcr_banks = sha256
|
|
fn persist_key() -> Result<()> {
|
|
fn persist_key() -> Result<()> {
|
|
let (_harness, store) = test_store()?;
|
|
let (_harness, store) = test_store()?;
|
|
let cookie = Cookie::random()?;
|
|
let cookie = Cookie::random()?;
|
|
- let params = KeyParams::with_unique(cookie.as_slice());
|
|
|
|
|
|
+ let params = KeyBuilder::new(Sign::RSA_PSS_3072_SHA_256, cookie.as_slice());
|
|
let pair = store.gen_key(params)?;
|
|
let pair = store.gen_key(params)?;
|
|
let mut guard = store.state.write().conv_err()?;
|
|
let mut guard = store.state.write().conv_err()?;
|
|
guard.context.persist_key(pair.private)?;
|
|
guard.context.persist_key(pair.private)?;
|