Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support bytes-like consistently across our asym sign/verify APIs #10260

Merged
merged 1 commit into from Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions docs/hazmat/primitives/asymmetric/dsa.rst
Expand Up @@ -289,7 +289,8 @@ Key interfaces
Sign one block of data which can be verified later by others using the
public key.

:param bytes data: The message string to sign.
:param data: The message string to sign.
:type data: :term:`bytes-like`

:param algorithm: An instance of
:class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` or
Expand Down Expand Up @@ -391,9 +392,11 @@ Key interfaces
Verify one block of data was signed by the private key
associated with this public key.

:param bytes signature: The signature to verify.
:param signature: The signature to verify.
:type signature: :term:`bytes-like`

:param bytes data: The message string that was signed.
:param data: The message string that was signed.
:type data: :term:`bytes-like`

:param algorithm: An instance of
:class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` or
Expand Down
9 changes: 6 additions & 3 deletions docs/hazmat/primitives/asymmetric/ec.rst
Expand Up @@ -569,7 +569,8 @@ Key Interfaces
Sign one block of data which can be verified later by others using the
public key.

:param bytes data: The message string to sign.
:param data: The message string to sign.
:type data: :term:`bytes-like`

:param signature_algorithm: An instance of
:class:`EllipticCurveSignatureAlgorithm`, such as :class:`ECDSA`.
Expand Down Expand Up @@ -678,12 +679,14 @@ Key Interfaces
Verify one block of data was signed by the private key associated
with this public key.

:param bytes signature: The DER-encoded signature to verify.
:param signature: The DER-encoded signature to verify.
A raw signature may be DER-encoded by splitting it into the ``r``
and ``s`` components and passing them into
:func:`~cryptography.hazmat.primitives.asymmetric.utils.encode_dss_signature`.
:type signature: :term:`bytes-like`

:param bytes data: The message string that was signed.
:param data: The message string that was signed.
:type data: :term:`bytes-like`

:param signature_algorithm: An instance of
:class:`EllipticCurveSignatureAlgorithm`.
Expand Down
9 changes: 6 additions & 3 deletions docs/hazmat/primitives/asymmetric/ed25519.rst
Expand Up @@ -67,7 +67,8 @@ Key interfaces

.. method:: sign(data)

:param bytes data: The data to sign.
:param data: The data to sign.
:type data: :term:`bytes-like`

:returns bytes: The 64 byte signature.

Expand Down Expand Up @@ -192,9 +193,11 @@ Key interfaces

.. method:: verify(signature, data)

:param bytes signature: The signature to verify.
:param signature: The signature to verify.
:type signature: :term:`bytes-like`

:param bytes data: The data to verify.
:param data: The data to verify.
:type data: :term:`bytes-like`

:returns: None
:raises cryptography.exceptions.InvalidSignature: Raised when the
Expand Down
9 changes: 6 additions & 3 deletions docs/hazmat/primitives/asymmetric/ed448.rst
Expand Up @@ -47,7 +47,8 @@ Key interfaces

.. method:: sign(data)

:param bytes data: The data to sign.
:param data: The data to sign.
:type data: :term:`bytes-like`

:returns bytes: The 114 byte signature.

Expand Down Expand Up @@ -146,9 +147,11 @@ Key interfaces

.. method:: verify(signature, data)

:param bytes signature: The signature to verify.
:param signature: The signature to verify.
:type signature: :term:`bytes-like`

:param bytes data: The data to verify.
:param data: The data to verify.
:type data: :term:`bytes-like`

:returns: None
:raises cryptography.exceptions.InvalidSignature: Raised when the
Expand Down
13 changes: 7 additions & 6 deletions src/rust/src/backend/dsa.rs
Expand Up @@ -3,6 +3,7 @@
// for complete details.

use crate::backend::utils;
use crate::buf::CffiBuf;
use crate::error::{CryptographyError, CryptographyResult};
use crate::exceptions;

Expand Down Expand Up @@ -66,10 +67,10 @@ impl DsaPrivateKey {
fn sign<'p>(
&self,
py: pyo3::Python<'p>,
data: &[u8],
data: CffiBuf<'_>,
algorithm: &pyo3::PyAny,
) -> CryptographyResult<&'p pyo3::types::PyBytes> {
let (data, _) = utils::calculate_digest_and_algorithm(py, data, algorithm)?;
let (data, _) = utils::calculate_digest_and_algorithm(py, data.as_bytes(), algorithm)?;

let mut signer = openssl::pkey_ctx::PkeyCtx::new(&self.pkey)?;
signer.sign_init()?;
Expand Down Expand Up @@ -151,15 +152,15 @@ impl DsaPublicKey {
fn verify(
&self,
py: pyo3::Python<'_>,
signature: &[u8],
data: &[u8],
signature: CffiBuf<'_>,
data: CffiBuf<'_>,
algorithm: &pyo3::PyAny,
) -> CryptographyResult<()> {
let (data, _) = utils::calculate_digest_and_algorithm(py, data, algorithm)?;
let (data, _) = utils::calculate_digest_and_algorithm(py, data.as_bytes(), algorithm)?;

let mut verifier = openssl::pkey_ctx::PkeyCtx::new(&self.pkey)?;
verifier.verify_init()?;
let valid = verifier.verify(data, signature).unwrap_or(false);
let valid = verifier.verify(data, signature.as_bytes()).unwrap_or(false);
if !valid {
return Err(CryptographyError::from(
exceptions::InvalidSignature::new_err(()),
Expand Down
13 changes: 7 additions & 6 deletions src/rust/src/backend/ec.rs
Expand Up @@ -8,6 +8,7 @@ use std::hash::{Hash, Hasher};
use pyo3::ToPyObject;

use crate::backend::utils;
use crate::buf::CffiBuf;
use crate::error::{CryptographyError, CryptographyResult};
use crate::{exceptions, types};

Expand Down Expand Up @@ -268,7 +269,7 @@ impl ECPrivateKey {
fn sign<'p>(
&self,
py: pyo3::Python<'p>,
data: &[u8],
data: CffiBuf<'_>,
signature_algorithm: &pyo3::PyAny,
) -> CryptographyResult<&'p pyo3::types::PyBytes> {
if !signature_algorithm.is_instance(types::ECDSA.get(py)?)? {
Expand All @@ -282,7 +283,7 @@ impl ECPrivateKey {

let (data, _) = utils::calculate_digest_and_algorithm(
py,
data,
data.as_bytes(),
signature_algorithm.getattr(pyo3::intern!(py, "algorithm"))?,
)?;

Expand Down Expand Up @@ -366,8 +367,8 @@ impl ECPublicKey {
fn verify(
&self,
py: pyo3::Python<'_>,
signature: &[u8],
data: &[u8],
signature: CffiBuf<'_>,
data: CffiBuf<'_>,
signature_algorithm: &pyo3::PyAny,
) -> CryptographyResult<()> {
if !signature_algorithm.is_instance(types::ECDSA.get(py)?)? {
Expand All @@ -381,13 +382,13 @@ impl ECPublicKey {

let (data, _) = utils::calculate_digest_and_algorithm(
py,
data,
data.as_bytes(),
signature_algorithm.getattr(pyo3::intern!(py, "algorithm"))?,
)?;

let mut verifier = openssl::pkey_ctx::PkeyCtx::new(&self.pkey)?;
verifier.verify_init()?;
let valid = verifier.verify(data, signature).unwrap_or(false);
let valid = verifier.verify(data, signature.as_bytes()).unwrap_or(false);
if !valid {
return Err(CryptographyError::from(
exceptions::InvalidSignature::new_err(()),
Expand Down
8 changes: 4 additions & 4 deletions src/rust/src/backend/ed25519.rs
Expand Up @@ -66,12 +66,12 @@ impl Ed25519PrivateKey {
fn sign<'p>(
&self,
py: pyo3::Python<'p>,
data: &[u8],
data: CffiBuf<'_>,
) -> CryptographyResult<&'p pyo3::types::PyBytes> {
let mut signer = openssl::sign::Signer::new_without_digest(&self.pkey)?;
Ok(pyo3::types::PyBytes::new_with(py, signer.len()?, |b| {
let n = signer
.sign_oneshot(b, data)
.sign_oneshot(b, data.as_bytes())
.map_err(CryptographyError::from)?;
assert_eq!(n, b.len());
Ok(())
Expand Down Expand Up @@ -118,9 +118,9 @@ impl Ed25519PrivateKey {

#[pyo3::prelude::pymethods]
impl Ed25519PublicKey {
fn verify(&self, signature: &[u8], data: &[u8]) -> CryptographyResult<()> {
fn verify(&self, signature: CffiBuf<'_>, data: CffiBuf<'_>) -> CryptographyResult<()> {
let valid = openssl::sign::Verifier::new_without_digest(&self.pkey)?
.verify_oneshot(signature, data)
.verify_oneshot(signature.as_bytes(), data.as_bytes())
.unwrap_or(false);

if !valid {
Expand Down
8 changes: 4 additions & 4 deletions src/rust/src/backend/ed448.rs
Expand Up @@ -64,12 +64,12 @@ impl Ed448PrivateKey {
fn sign<'p>(
&self,
py: pyo3::Python<'p>,
data: &[u8],
data: CffiBuf<'_>,
) -> CryptographyResult<&'p pyo3::types::PyBytes> {
let mut signer = openssl::sign::Signer::new_without_digest(&self.pkey)?;
Ok(pyo3::types::PyBytes::new_with(py, signer.len()?, |b| {
let n = signer
.sign_oneshot(b, data)
.sign_oneshot(b, data.as_bytes())
.map_err(CryptographyError::from)?;
assert_eq!(n, b.len());
Ok(())
Expand Down Expand Up @@ -116,9 +116,9 @@ impl Ed448PrivateKey {

#[pyo3::prelude::pymethods]
impl Ed448PublicKey {
fn verify(&self, signature: &[u8], data: &[u8]) -> CryptographyResult<()> {
fn verify(&self, signature: CffiBuf<'_>, data: CffiBuf<'_>) -> CryptographyResult<()> {
let valid = openssl::sign::Verifier::new_without_digest(&self.pkey)?
.verify_oneshot(signature, data)?;
.verify_oneshot(signature.as_bytes(), data.as_bytes())?;

if !valid {
return Err(CryptographyError::from(
Expand Down
8 changes: 8 additions & 0 deletions tests/hazmat/primitives/test_dsa.py
Expand Up @@ -522,6 +522,14 @@ def test_sign(self, backend):
public_key = private_key.public_key()
public_key.verify(signature, message, algorithm)

def test_sign_verify_buffer(self, backend):
private_key = DSA_KEY_1024.private_key(backend)
message = bytearray(b"one little message")
algorithm = hashes.SHA1()
signature = private_key.sign(message, algorithm)
public_key = private_key.public_key()
public_key.verify(bytearray(signature), message, algorithm)

def test_prehashed_sign(self, backend):
private_key = DSA_KEY_1024.private_key(backend)
message = b"one little message"
Expand Down
9 changes: 9 additions & 0 deletions tests/hazmat/primitives/test_ec.py
Expand Up @@ -516,6 +516,15 @@ def test_sign(self, backend):
public_key = private_key.public_key()
public_key.verify(signature, message, algorithm)

def test_sign_verify_buffers(self, backend):
_skip_curve_unsupported(backend, ec.SECP256R1())
message = bytearray(b"one little message")
algorithm = ec.ECDSA(hashes.SHA1())
private_key = ec.generate_private_key(ec.SECP256R1(), backend)
signature = private_key.sign(message, algorithm)
public_key = private_key.public_key()
public_key.verify(bytearray(signature), message, algorithm)

def test_sign_prehashed(self, backend):
_skip_curve_unsupported(backend, ec.SECP256R1())
message = b"one little message"
Expand Down
6 changes: 6 additions & 0 deletions tests/hazmat/primitives/test_ed25519.py
Expand Up @@ -117,6 +117,12 @@ def test_invalid_signature(self, backend):
with pytest.raises(InvalidSignature):
key.public_key().verify(b"0" * 64, b"test data")

def test_sign_verify_buffer(self, backend):
key = Ed25519PrivateKey.generate()
data = bytearray(b"test data")
signature = key.sign(data)
key.public_key().verify(bytearray(signature), data)

def test_generate(self, backend):
key = Ed25519PrivateKey.generate()
assert key
Expand Down
6 changes: 6 additions & 0 deletions tests/hazmat/primitives/test_ed448.py
Expand Up @@ -86,6 +86,12 @@ def test_invalid_signature(self, backend):
with pytest.raises(InvalidSignature):
key.public_key().verify(b"0" * 64, b"test data")

def test_sign_verify_buffer(self, backend):
key = Ed448PrivateKey.generate()
data = bytearray(b"test data")
signature = key.sign(data)
key.public_key().verify(bytearray(signature), data)

def test_generate(self, backend):
key = Ed448PrivateKey.generate()
assert key
Expand Down