Skip to content

bug(cryptography): BasicCredential::from_raw does not verify public key matches private key #3799

Description

@Sertug17

In crates/xmtp_cryptography/src/basic_credential.rs:120-130, the from_raw function constructs a SigningKey from caller-supplied private and public key bytes without verifying they correspond:

rust
fn from_raw(private: &[u8], public: &[u8]) -> Result<Self, ed25519_dalek::SignatureError> {
    let keypair = Zeroizing::new({
        let mut keypair = [0u8; 64];
        keypair[0..32].copy_from_slice(private);
        keypair[32..].copy_from_slice(public);
        keypair
    });
    let signing_key = SigningKey::from_keypair_bytes(&keypair)?;
    Ok(Self(Box::new(signing_key)))
}


SigningKey::from_keypair_bytes stores the public bytes verbatim without verifying that public == private * G (i.e., that the public key is the correct generator multiplied by the private key). A caller can supply (private_key_A, public_key_B) as a mismatched pair. The credential will sign with private_key_A but report public_key_B via verifying_key().

This is reachable through the serde Deserialize impl at line 267-269 of the same file.

Impact: An attacker who knows a victim's public key but not their private key can create a credential that signs with their own private key but claims the victim's public key. Any downstream verification that trusts the reported verifying_key() would accept signatures from the wrong party.

Suggested fix: After constructing the SigningKey, verify that signing_key.verifying_key().as_bytes() == public. If they don't match, return an error.

rust
let signing_key = SigningKey::from_keypair_bytes(&keypair)?;
if signing_key.verifying_key().as_bytes() != public {
    return Err(SignatureError::new());
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions