This commit is contained in:
2026-06-16 15:37:55 +05:30
parent 78887017a0
commit 6f4ac190c1
1786 changed files with 316067 additions and 100 deletions
@@ -0,0 +1,13 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
"""
Hazardous Materials
This is a "Hazardous Materials" module. You should ONLY use it if you're
100% absolutely sure that you know what you're doing because this module
is full of land mines, dragons, and dinosaurs with laser guns.
"""
@@ -0,0 +1,368 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
from cryptography.hazmat.bindings._rust import (
ObjectIdentifier as ObjectIdentifier,
)
from cryptography.hazmat.primitives import hashes
class ExtensionOID:
SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
KEY_USAGE = ObjectIdentifier("2.5.29.15")
PRIVATE_KEY_USAGE_PERIOD = ObjectIdentifier("2.5.29.16")
SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
ISSUING_DISTRIBUTION_POINT = ObjectIdentifier("2.5.29.28")
AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
TLS_FEATURE = ObjectIdentifier("1.3.6.1.5.5.7.1.24")
CRL_NUMBER = ObjectIdentifier("2.5.29.20")
DELTA_CRL_INDICATOR = ObjectIdentifier("2.5.29.27")
PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS = ObjectIdentifier(
"1.3.6.1.4.1.11129.2.4.2"
)
PRECERT_POISON = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.3")
SIGNED_CERTIFICATE_TIMESTAMPS = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.5")
MS_CERTIFICATE_TEMPLATE = ObjectIdentifier("1.3.6.1.4.1.311.21.7")
ADMISSIONS = ObjectIdentifier("1.3.36.8.3.3")
class OCSPExtensionOID:
NONCE = ObjectIdentifier("1.3.6.1.5.5.7.48.1.2")
ACCEPTABLE_RESPONSES = ObjectIdentifier("1.3.6.1.5.5.7.48.1.4")
class CRLEntryExtensionOID:
CERTIFICATE_ISSUER = ObjectIdentifier("2.5.29.29")
CRL_REASON = ObjectIdentifier("2.5.29.21")
INVALIDITY_DATE = ObjectIdentifier("2.5.29.24")
class NameOID:
COMMON_NAME = ObjectIdentifier("2.5.4.3")
COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
STREET_ADDRESS = ObjectIdentifier("2.5.4.9")
ORGANIZATION_IDENTIFIER = ObjectIdentifier("2.5.4.97")
ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
SURNAME = ObjectIdentifier("2.5.4.4")
GIVEN_NAME = ObjectIdentifier("2.5.4.42")
TITLE = ObjectIdentifier("2.5.4.12")
INITIALS = ObjectIdentifier("2.5.4.43")
GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
X500_UNIQUE_IDENTIFIER = ObjectIdentifier("2.5.4.45")
DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
PSEUDONYM = ObjectIdentifier("2.5.4.65")
USER_ID = ObjectIdentifier("0.9.2342.19200300.100.1.1")
DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
JURISDICTION_COUNTRY_NAME = ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.3")
JURISDICTION_LOCALITY_NAME = ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.1")
JURISDICTION_STATE_OR_PROVINCE_NAME = ObjectIdentifier(
"1.3.6.1.4.1.311.60.2.1.2"
)
BUSINESS_CATEGORY = ObjectIdentifier("2.5.4.15")
POSTAL_ADDRESS = ObjectIdentifier("2.5.4.16")
POSTAL_CODE = ObjectIdentifier("2.5.4.17")
INN = ObjectIdentifier("1.2.643.3.131.1.1")
OGRN = ObjectIdentifier("1.2.643.100.1")
SNILS = ObjectIdentifier("1.2.643.100.3")
UNSTRUCTURED_NAME = ObjectIdentifier("1.2.840.113549.1.9.2")
class SignatureAlgorithmOID:
RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
# This is an alternate OID for RSA with SHA1 that is occasionally seen
_RSA_WITH_SHA1 = ObjectIdentifier("1.3.14.3.2.29")
RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
RSA_WITH_SHA3_224 = ObjectIdentifier("2.16.840.1.101.3.4.3.13")
RSA_WITH_SHA3_256 = ObjectIdentifier("2.16.840.1.101.3.4.3.14")
RSA_WITH_SHA3_384 = ObjectIdentifier("2.16.840.1.101.3.4.3.15")
RSA_WITH_SHA3_512 = ObjectIdentifier("2.16.840.1.101.3.4.3.16")
RSASSA_PSS = ObjectIdentifier("1.2.840.113549.1.1.10")
ECDSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10045.4.1")
ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
ECDSA_WITH_SHA3_224 = ObjectIdentifier("2.16.840.1.101.3.4.3.9")
ECDSA_WITH_SHA3_256 = ObjectIdentifier("2.16.840.1.101.3.4.3.10")
ECDSA_WITH_SHA3_384 = ObjectIdentifier("2.16.840.1.101.3.4.3.11")
ECDSA_WITH_SHA3_512 = ObjectIdentifier("2.16.840.1.101.3.4.3.12")
DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
DSA_WITH_SHA384 = ObjectIdentifier("2.16.840.1.101.3.4.3.3")
DSA_WITH_SHA512 = ObjectIdentifier("2.16.840.1.101.3.4.3.4")
ED25519 = ObjectIdentifier("1.3.101.112")
ED448 = ObjectIdentifier("1.3.101.113")
ML_DSA_44 = ObjectIdentifier("2.16.840.1.101.3.4.3.17")
ML_DSA_65 = ObjectIdentifier("2.16.840.1.101.3.4.3.18")
ML_DSA_87 = ObjectIdentifier("2.16.840.1.101.3.4.3.19")
GOSTR3411_94_WITH_3410_2001 = ObjectIdentifier("1.2.643.2.2.3")
GOSTR3410_2012_WITH_3411_2012_256 = ObjectIdentifier("1.2.643.7.1.1.3.2")
GOSTR3410_2012_WITH_3411_2012_512 = ObjectIdentifier("1.2.643.7.1.1.3.3")
_SIG_OIDS_TO_HASH: dict[ObjectIdentifier, hashes.HashAlgorithm | None] = {
SignatureAlgorithmOID.RSA_WITH_MD5: hashes.MD5(),
SignatureAlgorithmOID.RSA_WITH_SHA1: hashes.SHA1(),
SignatureAlgorithmOID._RSA_WITH_SHA1: hashes.SHA1(),
SignatureAlgorithmOID.RSA_WITH_SHA224: hashes.SHA224(),
SignatureAlgorithmOID.RSA_WITH_SHA256: hashes.SHA256(),
SignatureAlgorithmOID.RSA_WITH_SHA384: hashes.SHA384(),
SignatureAlgorithmOID.RSA_WITH_SHA512: hashes.SHA512(),
SignatureAlgorithmOID.RSA_WITH_SHA3_224: hashes.SHA3_224(),
SignatureAlgorithmOID.RSA_WITH_SHA3_256: hashes.SHA3_256(),
SignatureAlgorithmOID.RSA_WITH_SHA3_384: hashes.SHA3_384(),
SignatureAlgorithmOID.RSA_WITH_SHA3_512: hashes.SHA3_512(),
SignatureAlgorithmOID.ECDSA_WITH_SHA1: hashes.SHA1(),
SignatureAlgorithmOID.ECDSA_WITH_SHA224: hashes.SHA224(),
SignatureAlgorithmOID.ECDSA_WITH_SHA256: hashes.SHA256(),
SignatureAlgorithmOID.ECDSA_WITH_SHA384: hashes.SHA384(),
SignatureAlgorithmOID.ECDSA_WITH_SHA512: hashes.SHA512(),
SignatureAlgorithmOID.ECDSA_WITH_SHA3_224: hashes.SHA3_224(),
SignatureAlgorithmOID.ECDSA_WITH_SHA3_256: hashes.SHA3_256(),
SignatureAlgorithmOID.ECDSA_WITH_SHA3_384: hashes.SHA3_384(),
SignatureAlgorithmOID.ECDSA_WITH_SHA3_512: hashes.SHA3_512(),
SignatureAlgorithmOID.DSA_WITH_SHA1: hashes.SHA1(),
SignatureAlgorithmOID.DSA_WITH_SHA224: hashes.SHA224(),
SignatureAlgorithmOID.DSA_WITH_SHA256: hashes.SHA256(),
SignatureAlgorithmOID.ED25519: None,
SignatureAlgorithmOID.ED448: None,
SignatureAlgorithmOID.ML_DSA_44: None,
SignatureAlgorithmOID.ML_DSA_65: None,
SignatureAlgorithmOID.ML_DSA_87: None,
SignatureAlgorithmOID.GOSTR3411_94_WITH_3410_2001: None,
SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_256: None,
SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_512: None,
}
class HashAlgorithmOID:
SHA1 = ObjectIdentifier("1.3.14.3.2.26")
SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.2.4")
SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.2.1")
SHA384 = ObjectIdentifier("2.16.840.1.101.3.4.2.2")
SHA512 = ObjectIdentifier("2.16.840.1.101.3.4.2.3")
SHA3_224 = ObjectIdentifier("1.3.6.1.4.1.37476.3.2.1.99.7.224")
SHA3_256 = ObjectIdentifier("1.3.6.1.4.1.37476.3.2.1.99.7.256")
SHA3_384 = ObjectIdentifier("1.3.6.1.4.1.37476.3.2.1.99.7.384")
SHA3_512 = ObjectIdentifier("1.3.6.1.4.1.37476.3.2.1.99.7.512")
SHA3_224_NIST = ObjectIdentifier("2.16.840.1.101.3.4.2.7")
SHA3_256_NIST = ObjectIdentifier("2.16.840.1.101.3.4.2.8")
SHA3_384_NIST = ObjectIdentifier("2.16.840.1.101.3.4.2.9")
SHA3_512_NIST = ObjectIdentifier("2.16.840.1.101.3.4.2.10")
class PublicKeyAlgorithmOID:
DSA = ObjectIdentifier("1.2.840.10040.4.1")
EC_PUBLIC_KEY = ObjectIdentifier("1.2.840.10045.2.1")
RSAES_PKCS1_v1_5 = ObjectIdentifier("1.2.840.113549.1.1.1")
RSASSA_PSS = ObjectIdentifier("1.2.840.113549.1.1.10")
X25519 = ObjectIdentifier("1.3.101.110")
X448 = ObjectIdentifier("1.3.101.111")
ED25519 = ObjectIdentifier("1.3.101.112")
ED448 = ObjectIdentifier("1.3.101.113")
ML_DSA_44 = ObjectIdentifier("2.16.840.1.101.3.4.3.17")
ML_DSA_65 = ObjectIdentifier("2.16.840.1.101.3.4.3.18")
ML_DSA_87 = ObjectIdentifier("2.16.840.1.101.3.4.3.19")
class ExtendedKeyUsageOID:
SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
ANY_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37.0")
SMARTCARD_LOGON = ObjectIdentifier("1.3.6.1.4.1.311.20.2.2")
KERBEROS_PKINIT_KDC = ObjectIdentifier("1.3.6.1.5.2.3.5")
IPSEC_IKE = ObjectIdentifier("1.3.6.1.5.5.7.3.17")
BUNDLE_SECURITY = ObjectIdentifier("1.3.6.1.5.5.7.3.35")
CERTIFICATE_TRANSPARENCY = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.4")
class OtherNameFormOID:
PERMANENT_IDENTIFIER = ObjectIdentifier("1.3.6.1.5.5.7.8.3")
HW_MODULE_NAME = ObjectIdentifier("1.3.6.1.5.5.7.8.4")
DNS_SRV = ObjectIdentifier("1.3.6.1.5.5.7.8.7")
NAI_REALM = ObjectIdentifier("1.3.6.1.5.5.7.8.8")
SMTP_UTF8_MAILBOX = ObjectIdentifier("1.3.6.1.5.5.7.8.9")
ACP_NODE_NAME = ObjectIdentifier("1.3.6.1.5.5.7.8.10")
BUNDLE_EID = ObjectIdentifier("1.3.6.1.5.5.7.8.11")
class AuthorityInformationAccessOID:
CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2")
OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1")
class SubjectInformationAccessOID:
CA_REPOSITORY = ObjectIdentifier("1.3.6.1.5.5.7.48.5")
class CertificatePoliciesOID:
CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1")
CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2")
ANY_POLICY = ObjectIdentifier("2.5.29.32.0")
class AttributeOID:
CHALLENGE_PASSWORD = ObjectIdentifier("1.2.840.113549.1.9.7")
UNSTRUCTURED_NAME = ObjectIdentifier("1.2.840.113549.1.9.2")
_OID_NAMES = {
NameOID.COMMON_NAME: "commonName",
NameOID.COUNTRY_NAME: "countryName",
NameOID.LOCALITY_NAME: "localityName",
NameOID.STATE_OR_PROVINCE_NAME: "stateOrProvinceName",
NameOID.STREET_ADDRESS: "streetAddress",
NameOID.ORGANIZATION_NAME: "organizationName",
NameOID.ORGANIZATIONAL_UNIT_NAME: "organizationalUnitName",
NameOID.SERIAL_NUMBER: "serialNumber",
NameOID.SURNAME: "surname",
NameOID.GIVEN_NAME: "givenName",
NameOID.TITLE: "title",
NameOID.GENERATION_QUALIFIER: "generationQualifier",
NameOID.X500_UNIQUE_IDENTIFIER: "x500UniqueIdentifier",
NameOID.DN_QUALIFIER: "dnQualifier",
NameOID.PSEUDONYM: "pseudonym",
NameOID.USER_ID: "userID",
NameOID.DOMAIN_COMPONENT: "domainComponent",
NameOID.EMAIL_ADDRESS: "emailAddress",
NameOID.JURISDICTION_COUNTRY_NAME: "jurisdictionCountryName",
NameOID.JURISDICTION_LOCALITY_NAME: "jurisdictionLocalityName",
NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME: (
"jurisdictionStateOrProvinceName"
),
NameOID.BUSINESS_CATEGORY: "businessCategory",
NameOID.POSTAL_ADDRESS: "postalAddress",
NameOID.POSTAL_CODE: "postalCode",
NameOID.INN: "INN",
NameOID.OGRN: "OGRN",
NameOID.SNILS: "SNILS",
NameOID.UNSTRUCTURED_NAME: "unstructuredName",
SignatureAlgorithmOID.RSA_WITH_MD5: "md5WithRSAEncryption",
SignatureAlgorithmOID.RSA_WITH_SHA1: "sha1WithRSAEncryption",
SignatureAlgorithmOID.RSA_WITH_SHA224: "sha224WithRSAEncryption",
SignatureAlgorithmOID.RSA_WITH_SHA256: "sha256WithRSAEncryption",
SignatureAlgorithmOID.RSA_WITH_SHA384: "sha384WithRSAEncryption",
SignatureAlgorithmOID.RSA_WITH_SHA512: "sha512WithRSAEncryption",
SignatureAlgorithmOID.RSASSA_PSS: "rsassaPss",
SignatureAlgorithmOID.ECDSA_WITH_SHA1: "ecdsa-with-SHA1",
SignatureAlgorithmOID.ECDSA_WITH_SHA224: "ecdsa-with-SHA224",
SignatureAlgorithmOID.ECDSA_WITH_SHA256: "ecdsa-with-SHA256",
SignatureAlgorithmOID.ECDSA_WITH_SHA384: "ecdsa-with-SHA384",
SignatureAlgorithmOID.ECDSA_WITH_SHA512: "ecdsa-with-SHA512",
SignatureAlgorithmOID.DSA_WITH_SHA1: "dsa-with-sha1",
SignatureAlgorithmOID.DSA_WITH_SHA224: "dsa-with-sha224",
SignatureAlgorithmOID.DSA_WITH_SHA256: "dsa-with-sha256",
SignatureAlgorithmOID.ED25519: "ed25519",
SignatureAlgorithmOID.ED448: "ed448",
SignatureAlgorithmOID.ML_DSA_44: "ML-DSA-44",
SignatureAlgorithmOID.ML_DSA_65: "ML-DSA-65",
SignatureAlgorithmOID.ML_DSA_87: "ML-DSA-87",
SignatureAlgorithmOID.GOSTR3411_94_WITH_3410_2001: (
"GOST R 34.11-94 with GOST R 34.10-2001"
),
SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_256: (
"GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)"
),
SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_512: (
"GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)"
),
HashAlgorithmOID.SHA1: "sha1",
HashAlgorithmOID.SHA224: "sha224",
HashAlgorithmOID.SHA256: "sha256",
HashAlgorithmOID.SHA384: "sha384",
HashAlgorithmOID.SHA512: "sha512",
HashAlgorithmOID.SHA3_224: "sha3_224",
HashAlgorithmOID.SHA3_256: "sha3_256",
HashAlgorithmOID.SHA3_384: "sha3_384",
HashAlgorithmOID.SHA3_512: "sha3_512",
HashAlgorithmOID.SHA3_224_NIST: "sha3_224",
HashAlgorithmOID.SHA3_256_NIST: "sha3_256",
HashAlgorithmOID.SHA3_384_NIST: "sha3_384",
HashAlgorithmOID.SHA3_512_NIST: "sha3_512",
PublicKeyAlgorithmOID.DSA: "dsaEncryption",
PublicKeyAlgorithmOID.EC_PUBLIC_KEY: "id-ecPublicKey",
PublicKeyAlgorithmOID.RSAES_PKCS1_v1_5: "rsaEncryption",
PublicKeyAlgorithmOID.X25519: "X25519",
PublicKeyAlgorithmOID.X448: "X448",
ExtendedKeyUsageOID.SERVER_AUTH: "serverAuth",
ExtendedKeyUsageOID.CLIENT_AUTH: "clientAuth",
ExtendedKeyUsageOID.CODE_SIGNING: "codeSigning",
ExtendedKeyUsageOID.EMAIL_PROTECTION: "emailProtection",
ExtendedKeyUsageOID.TIME_STAMPING: "timeStamping",
ExtendedKeyUsageOID.OCSP_SIGNING: "OCSPSigning",
ExtendedKeyUsageOID.SMARTCARD_LOGON: "msSmartcardLogin",
ExtendedKeyUsageOID.KERBEROS_PKINIT_KDC: "pkInitKDC",
ExtensionOID.SUBJECT_DIRECTORY_ATTRIBUTES: "subjectDirectoryAttributes",
ExtensionOID.SUBJECT_KEY_IDENTIFIER: "subjectKeyIdentifier",
ExtensionOID.KEY_USAGE: "keyUsage",
ExtensionOID.PRIVATE_KEY_USAGE_PERIOD: "privateKeyUsagePeriod",
ExtensionOID.SUBJECT_ALTERNATIVE_NAME: "subjectAltName",
ExtensionOID.ISSUER_ALTERNATIVE_NAME: "issuerAltName",
ExtensionOID.BASIC_CONSTRAINTS: "basicConstraints",
ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS: (
"signedCertificateTimestampList"
),
ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS: (
"signedCertificateTimestampList"
),
ExtensionOID.PRECERT_POISON: "ctPoison",
ExtensionOID.MS_CERTIFICATE_TEMPLATE: "msCertificateTemplate",
ExtensionOID.ADMISSIONS: "Admissions",
CRLEntryExtensionOID.CRL_REASON: "cRLReason",
CRLEntryExtensionOID.INVALIDITY_DATE: "invalidityDate",
CRLEntryExtensionOID.CERTIFICATE_ISSUER: "certificateIssuer",
ExtensionOID.NAME_CONSTRAINTS: "nameConstraints",
ExtensionOID.CRL_DISTRIBUTION_POINTS: "cRLDistributionPoints",
ExtensionOID.CERTIFICATE_POLICIES: "certificatePolicies",
ExtensionOID.POLICY_MAPPINGS: "policyMappings",
ExtensionOID.AUTHORITY_KEY_IDENTIFIER: "authorityKeyIdentifier",
ExtensionOID.POLICY_CONSTRAINTS: "policyConstraints",
ExtensionOID.EXTENDED_KEY_USAGE: "extendedKeyUsage",
ExtensionOID.FRESHEST_CRL: "freshestCRL",
ExtensionOID.INHIBIT_ANY_POLICY: "inhibitAnyPolicy",
ExtensionOID.ISSUING_DISTRIBUTION_POINT: "issuingDistributionPoint",
ExtensionOID.AUTHORITY_INFORMATION_ACCESS: "authorityInfoAccess",
ExtensionOID.SUBJECT_INFORMATION_ACCESS: "subjectInfoAccess",
ExtensionOID.OCSP_NO_CHECK: "OCSPNoCheck",
ExtensionOID.CRL_NUMBER: "cRLNumber",
ExtensionOID.DELTA_CRL_INDICATOR: "deltaCRLIndicator",
ExtensionOID.TLS_FEATURE: "TLSFeature",
AuthorityInformationAccessOID.OCSP: "OCSP",
AuthorityInformationAccessOID.CA_ISSUERS: "caIssuers",
SubjectInformationAccessOID.CA_REPOSITORY: "caRepository",
CertificatePoliciesOID.CPS_QUALIFIER: "id-qt-cps",
CertificatePoliciesOID.CPS_USER_NOTICE: "id-qt-unotice",
OCSPExtensionOID.NONCE: "OCSPNonce",
AttributeOID.CHALLENGE_PASSWORD: "challengePassword",
}
@@ -0,0 +1,45 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.asn1.asn1 import (
TLV,
BitString,
Default,
Explicit,
GeneralizedTime,
IA5String,
Implicit,
Null,
PrintableString,
SetOf,
Size,
UTCTime,
Variant,
decode_der,
encode_der,
sequence,
set,
value_set,
)
__all__ = [
"TLV",
"BitString",
"Default",
"Explicit",
"GeneralizedTime",
"IA5String",
"Implicit",
"Null",
"PrintableString",
"SetOf",
"Size",
"UTCTime",
"Variant",
"decode_der",
"encode_der",
"sequence",
"set",
"value_set",
]
@@ -0,0 +1,533 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import builtins
import dataclasses
import enum
import sys
import types
import typing
if sys.version_info < (3, 11):
import typing_extensions
LiteralString = typing_extensions.LiteralString
else:
LiteralString = typing.LiteralString
from cryptography.hazmat.bindings._rust import declarative_asn1
from cryptography.hazmat.bindings._rust import x509 as rust_x509
if sys.version_info < (3, 10):
NoneType = type(None)
else:
NoneType = types.NoneType # type: ignore[nonetype-type]
T = typing.TypeVar("T", covariant=True)
U = typing.TypeVar("U")
Tag = typing.TypeVar("Tag", bound=LiteralString)
@dataclasses.dataclass(frozen=True)
class Variant(typing.Generic[U, Tag]):
"""
A tagged variant for CHOICE fields with the same underlying type.
Use this when you have multiple CHOICE alternatives with the same type
and need to distinguish between them:
foo: (
Annotated[Variant[int, typing.Literal["IntA"]], Implicit(0)]
| Annotated[Variant[int, typing.Literal["IntB"]], Implicit(1)]
)
Usage:
example = Example(foo=Variant(5, "IntA"))
decoded.foo.value # The int value
decoded.foo.tag # "IntA" or "IntB"
"""
value: U
tag: str
decode_der = declarative_asn1.decode_der
encode_der = declarative_asn1.encode_der
_X509_TYPES = (
rust_x509.Certificate,
rust_x509.CertificateSigningRequest,
rust_x509.CertificateRevocationList,
)
def _check_x509_field_annotations(
field_type: typing.Any,
annotation: declarative_asn1.Annotation,
field_name: str,
) -> None:
if field_type in _X509_TYPES and isinstance(annotation.encoding, Implicit):
raise TypeError(
f"field '{field_name}' has an IMPLICIT annotation, but "
"IMPLICIT annotations are not supported for X.509 types."
)
def _is_union(field_type: type) -> bool:
# NOTE: types.UnionType for `T | U`, typing.Union for `Union[T, U]`.
# TODO: Drop the `hasattr()` once the minimum supported Python version
# is >= 3.10.
union_types = (
(types.UnionType, typing.Union)
if hasattr(types, "UnionType")
else (typing.Union,)
)
return typing.get_origin(field_type) in union_types
def _resolve_type_aliases(field_type: typing.Any) -> typing.Any:
# Recursively resolve PEP 695 (`type X = ...`) type aliases (Python
# 3.12+) to their underlying value, so that the rest of the
# normalization logic never encounters an alias. Aliases can refer
# to other aliases and can appear at any level of nesting (e.g.
# inside `Annotated[...]`, unions, or `list[...]`).
if sys.version_info < (3, 12):
return field_type
while isinstance(field_type, typing.TypeAliasType):
field_type = field_type.__value__
args = typing.get_args(field_type)
resolved_args = tuple(_resolve_type_aliases(arg) for arg in args)
if resolved_args == args:
# No aliases anywhere inside: return the type unchanged.
return field_type
if _is_union(field_type):
# `X | Y` unions can't be rebuilt through their origin like
# other generics below: `typing.get_origin` returns
# `types.UnionType` for them, which is only subscriptable on
# Python 3.14+. Rebuilding through `typing.Union` also
# flattens any nested union introduced by an alias of a union
# (e.g. `Time | int` where `type Time = UTCTime |
# GeneralizedTime`), just like `typing.Union` would have done
# if the alias had been written inline.
return typing.Union[resolved_args]
# An alias appeared inside a generic (e.g. `Annotated[Time, ...]`,
# `list[MyInt]`, or `SetOf[MyInt]`): re-parameterize the generic
# with the resolved arguments. Subscripting with a tuple is
# equivalent to subscripting with multiple arguments.
return typing.get_origin(field_type)[resolved_args]
def _extract_annotation(
metadata: tuple, field_name: str
) -> declarative_asn1.Annotation:
default = None
encoding = None
size = None
for raw_annotation in metadata:
if isinstance(raw_annotation, Default):
if default is not None:
raise TypeError(
f"multiple DEFAULT annotations found in field "
f"'{field_name}'"
)
default = raw_annotation.value
elif isinstance(raw_annotation, declarative_asn1.Encoding):
if encoding is not None:
raise TypeError(
f"multiple IMPLICIT/EXPLICIT annotations found in field "
f"'{field_name}'"
)
encoding = raw_annotation
elif isinstance(raw_annotation, declarative_asn1.Size):
if size is not None:
raise TypeError(
f"multiple SIZE annotations found in field '{field_name}'"
)
size = raw_annotation
else:
raise TypeError(f"unsupported annotation: {raw_annotation}")
return declarative_asn1.Annotation(
default=default, encoding=encoding, size=size
)
def _normalize_field_type(
field_type: typing.Any, field_name: str
) -> declarative_asn1.AnnotatedType:
field_type = _resolve_type_aliases(field_type)
# Strip the `Annotated[...]` off, and populate the annotation
# from it if it exists.
if typing.get_origin(field_type) is typing.Annotated:
annotation = _extract_annotation(field_type.__metadata__, field_name)
field_type, *_ = typing.get_args(field_type)
else:
annotation = declarative_asn1.Annotation()
if annotation.size is not None and (
typing.get_origin(field_type) not in (builtins.list, SetOf)
and field_type
not in (
builtins.bytes,
builtins.str,
BitString,
IA5String,
PrintableString,
)
):
raise TypeError(
f"field '{field_name}' has a SIZE annotation, but SIZE "
"annotations are only supported for fields of types: "
"[SEQUENCE OF, SET OF, BIT STRING, OCTET STRING, UTF8String, "
"PrintableString, IA5String]"
)
if field_type is TLV:
if isinstance(annotation.encoding, Implicit):
raise TypeError(
f"field '{field_name}' has an IMPLICIT annotation, but "
"IMPLICIT annotations are not supported for TLV types."
)
elif annotation.default is not None:
raise TypeError(
f"field '{field_name}' has a DEFAULT annotation, but "
"DEFAULT annotations are not supported for TLV types."
)
_check_x509_field_annotations(field_type, annotation, field_name)
if hasattr(field_type, "__asn1_root__"):
root_type = field_type.__asn1_root__
if not isinstance(
root_type,
(
declarative_asn1.Type.Sequence,
declarative_asn1.Type.Set,
declarative_asn1.Type.ValueSet,
),
):
raise TypeError(f"unsupported root type: {root_type}")
return declarative_asn1.AnnotatedType(
typing.cast(declarative_asn1.Type, root_type), annotation
)
elif _is_union(field_type):
union_args = typing.get_args(field_type)
if len(union_args) == 2 and NoneType in union_args:
# A Union between a type and None is an OPTIONAL
optional_type = (
union_args[0] if union_args[1] is type(None) else union_args[1]
)
if optional_type is TLV:
raise TypeError(
"optional TLV types (`TLV | None`) are not "
"currently supported"
)
# For optional types, the annotation is associated with the
# union, so we check it against the inner type here.
_check_x509_field_annotations(
optional_type, annotation, field_name
)
annotated_type = _normalize_field_type(optional_type, field_name)
if not annotated_type.annotation.is_empty():
raise TypeError(
"optional (`X | None`) types cannot have `X` "
"annotated: annotations must apply to the union "
"(i.e: `Annotated[X | None, annotation]`)"
)
if annotation.default is not None:
raise TypeError(
"optional (`X | None`) types should not have a DEFAULT "
"annotation"
)
rust_field_type = declarative_asn1.Type.Option(annotated_type)
else:
# Otherwise, the Union is a CHOICE
if isinstance(annotation.encoding, Implicit):
# CHOICEs cannot be IMPLICIT. See X.680 section 31.2.9.
raise TypeError(
"CHOICE (`X | Y | ...`) types should not have an IMPLICIT "
"annotation"
)
variants = [
_type_to_variant(arg, field_name)
for arg in union_args
if arg is not type(None)
]
# Union types should either be all Variants
# (`Variant[..] | Variant[..] | etc`) or all non Variants
are_union_types_tagged = variants[0].tag_name is not None
if any(
(v.tag_name is not None) != are_union_types_tagged
for v in variants
):
raise TypeError(
"When using `asn1.Variant` in a union, all the other "
"types in the union must also be `asn1.Variant`"
)
if are_union_types_tagged:
tags = {v.tag_name for v in variants}
if len(variants) != len(tags):
raise TypeError(
"When using `asn1.Variant` in a union, the tags used "
"must be unique"
)
rust_choice_type = declarative_asn1.Type.Choice(variants)
# If None is part of the union types, this is an OPTIONAL CHOICE
rust_field_type = (
declarative_asn1.Type.Option(
declarative_asn1.AnnotatedType(
rust_choice_type, declarative_asn1.Annotation()
)
)
if NoneType in union_args
else rust_choice_type
)
elif typing.get_origin(field_type) is builtins.list:
inner_type = _normalize_field_type(
typing.get_args(field_type)[0], field_name
)
rust_field_type = declarative_asn1.Type.SequenceOf(inner_type)
elif typing.get_origin(field_type) is SetOf:
inner_type = _normalize_field_type(
typing.get_args(field_type)[0], field_name
)
rust_field_type = declarative_asn1.Type.SetOf(inner_type)
else:
rust_field_type = declarative_asn1.non_root_python_to_rust(field_type)
return declarative_asn1.AnnotatedType(rust_field_type, annotation)
# Convert a type to a Variant. Used with types inside Union
# annotations (T1, T2, etc in `Union[T1, T2, ...]`).
def _type_to_variant(
t: typing.Any, field_name: str
) -> declarative_asn1.Variant:
is_annotated = typing.get_origin(t) is typing.Annotated
inner_type = typing.get_args(t)[0] if is_annotated else t
# Check if this is a Variant[T, Tag] type
if typing.get_origin(inner_type) is Variant:
value_type, tag_literal = typing.get_args(inner_type)
if typing.get_origin(tag_literal) is not typing.Literal:
raise TypeError(
"When using `asn1.Variant` in a type annotation, the second "
"type parameter must be a `typing.Literal` type. E.g: "
'`Variant[int, typing.Literal["MyInt"]]`.'
)
tag_name = typing.get_args(tag_literal)[0]
if hasattr(value_type, "__asn1_root__"):
rust_type = value_type.__asn1_root__
else:
rust_type = declarative_asn1.non_root_python_to_rust(value_type)
if is_annotated:
ann_type = declarative_asn1.AnnotatedType(
rust_type,
_extract_annotation(t.__metadata__, field_name),
)
else:
ann_type = declarative_asn1.AnnotatedType(
rust_type,
declarative_asn1.Annotation(),
)
return declarative_asn1.Variant(Variant, ann_type, tag_name)
else:
# Plain type (not a tagged Variant)
return declarative_asn1.Variant(
inner_type,
_normalize_field_type(t, field_name),
None,
)
def _annotate_fields(
raw_fields: dict[str, type],
) -> dict[str, declarative_asn1.AnnotatedType]:
fields = {}
for field_name, field_type in raw_fields.items():
# Recursively normalize the field type into something that the
# Rust code can understand.
annotated_field_type = _normalize_field_type(field_type, field_name)
fields[field_name] = annotated_field_type
return fields
def _register_asn1_sequence(cls: type[U]) -> None:
raw_fields = typing.get_type_hints(cls, include_extras=True)
root = declarative_asn1.Type.Sequence(cls, _annotate_fields(raw_fields))
setattr(cls, "__asn1_root__", root)
def _register_asn1_set(cls: type[U]) -> None:
raw_fields = typing.get_type_hints(cls, include_extras=True)
root = declarative_asn1.Type.Set(cls, _annotate_fields(raw_fields))
setattr(cls, "__asn1_root__", root)
# Due to https://github.com/python/mypy/issues/19731, we can't define an alias
# for `dataclass_transform` that conditionally points to `typing` or
# `typing_extensions` depending on the Python version. We work around it by
# making the whole decorated class conditional on the Python version.
if sys.version_info < (3, 11):
@typing_extensions.dataclass_transform(kw_only_default=True)
def sequence(cls: type[U]) -> type[U]:
# We use `dataclasses.dataclass` to add an __init__ method
# to the class with keyword-only parameters.
if sys.version_info >= (3, 10):
dataclass_cls = dataclasses.dataclass(
repr=False,
eq=False,
# `match_args` was added in Python 3.10 and defaults
# to True
match_args=False,
# `kw_only` was added in Python 3.10 and defaults to
# False
kw_only=True,
)(cls)
else:
dataclass_cls = dataclasses.dataclass(
repr=False,
eq=False,
)(cls)
_register_asn1_sequence(dataclass_cls)
return dataclass_cls
@typing_extensions.dataclass_transform(kw_only_default=True)
def set(cls: type[U]) -> type[U]:
# We use `dataclasses.dataclass` to add an __init__ method
# to the class with keyword-only parameters.
if sys.version_info >= (3, 10):
dataclass_cls = dataclasses.dataclass(
repr=False,
eq=False,
# `match_args` was added in Python 3.10 and defaults
# to True
match_args=False,
# `kw_only` was added in Python 3.10 and defaults to
# False
kw_only=True,
)(cls)
else:
dataclass_cls = dataclasses.dataclass(
repr=False,
eq=False,
)(cls)
_register_asn1_set(dataclass_cls)
return dataclass_cls
else:
@typing.dataclass_transform(kw_only_default=True)
def sequence(cls: type[U]) -> type[U]:
# Only add an __init__ method, with keyword-only
# parameters.
dataclass_cls = dataclasses.dataclass(
repr=False,
eq=False,
match_args=False,
kw_only=True,
)(cls)
_register_asn1_sequence(dataclass_cls)
return dataclass_cls
@typing.dataclass_transform(kw_only_default=True)
def set(cls: type[U]) -> type[U]:
# Only add an __init__ method, with keyword-only
# parameters.
dataclass_cls = dataclasses.dataclass(
repr=False,
eq=False,
match_args=False,
kw_only=True,
)(cls)
_register_asn1_set(dataclass_cls)
return dataclass_cls
def value_set(
value_type: type,
) -> typing.Callable[[type[U]], type[U]]:
"""
A class decorator that registers an `enum.Enum` subclass as an
ASN.1 value set of the given underlying type. All the member
values must be instances of `value_type`. Members are encoded as
their value; decoding fails if the decoded value does not match
any member.
"""
rust_type = declarative_asn1.non_root_python_to_rust(value_type)
def decorator(cls: type[U]) -> type[U]:
if not issubclass(cls, enum.Enum):
raise TypeError(
"value sets can only be defined from enum.Enum subclasses"
)
members = list(cls)
if not members:
raise TypeError(
f"value set '{cls.__name__}' must have at least one member"
)
for member in members:
if not isinstance(member.value, value_type):
raise TypeError(
f"member '{member.name}' of value set '{cls.__name__}' "
f"must have a value of type "
f"'{value_type.__name__}', got: "
f"'{type(member.value).__name__}'"
)
inner = declarative_asn1.AnnotatedType(
rust_type, declarative_asn1.Annotation()
)
# Map from member value to member, used for O(1) lookups when
# decoding. This requires the member values to be hashable.
value_map = {member.value: member for member in members}
root = declarative_asn1.Type.ValueSet(cls, inner, value_map)
setattr(cls, "__asn1_root__", root)
return cls
return decorator
# TODO: replace with `Default[U]` once the min Python version is >= 3.12
@dataclasses.dataclass(frozen=True)
class Default(typing.Generic[U]):
value: U
SetOf = declarative_asn1.SetOf
Explicit = declarative_asn1.Encoding.Explicit
Implicit = declarative_asn1.Encoding.Implicit
Size = declarative_asn1.Size
PrintableString = declarative_asn1.PrintableString
IA5String = declarative_asn1.IA5String
UTCTime = declarative_asn1.UTCTime
GeneralizedTime = declarative_asn1.GeneralizedTime
BitString = declarative_asn1.BitString
TLV = declarative_asn1.Tlv
Null = declarative_asn1.Null
@@ -0,0 +1,13 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
from typing import Any
def default_backend() -> Any:
from cryptography.hazmat.backends.openssl.backend import backend
return backend
@@ -0,0 +1,9 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
from cryptography.hazmat.backends.openssl.backend import backend
__all__ = ["backend"]
@@ -0,0 +1,314 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.bindings.openssl import binding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
from cryptography.hazmat.primitives.asymmetric.padding import (
MGF1,
OAEP,
PSS,
PKCS1v15,
)
from cryptography.hazmat.primitives.ciphers import (
CipherAlgorithm,
)
from cryptography.hazmat.primitives.ciphers.algorithms import (
AES,
)
from cryptography.hazmat.primitives.ciphers.modes import (
CBC,
Mode,
)
class Backend:
"""
OpenSSL API binding interfaces.
"""
name = "openssl"
# TripleDES encryption is disallowed/deprecated throughout 2023 in
# FIPS 140-3. To keep it simple we denylist any use of TripleDES (TDEA).
_fips_ciphers = (AES,)
# Sometimes SHA1 is still permissible. That logic is contained
# within the various *_supported methods.
_fips_hashes = (
hashes.SHA224,
hashes.SHA256,
hashes.SHA384,
hashes.SHA512,
hashes.SHA512_224,
hashes.SHA512_256,
hashes.SHA3_224,
hashes.SHA3_256,
hashes.SHA3_384,
hashes.SHA3_512,
hashes.SHAKE128,
hashes.SHAKE256,
)
_fips_ecdh_curves = (
ec.SECP224R1,
ec.SECP256R1,
ec.SECP384R1,
ec.SECP521R1,
)
_fips_rsa_min_key_size = 2048
_fips_rsa_min_public_exponent = 65537
_fips_dsa_min_modulus = 1 << 2048
_fips_dh_min_key_size = 2048
_fips_dh_min_modulus = 1 << _fips_dh_min_key_size
def __init__(self) -> None:
self._binding = binding.Binding()
self._ffi = self._binding.ffi
self._lib = self._binding.lib
self._fips_enabled = rust_openssl.is_fips_enabled()
def __repr__(self) -> str:
return (
f"<OpenSSLBackend(version: {self.openssl_version_text()}, "
f"FIPS: {self._fips_enabled}, "
f"Legacy: {rust_openssl._legacy_provider_loaded})>"
)
def openssl_assert(self, ok: bool) -> None:
return binding._openssl_assert(ok)
def _enable_fips(self) -> None:
# This function enables FIPS mode for OpenSSL 3.0.0 on installs that
# have the FIPS provider installed properly.
rust_openssl.enable_fips(rust_openssl._providers)
assert rust_openssl.is_fips_enabled()
self._fips_enabled = rust_openssl.is_fips_enabled()
def openssl_version_text(self) -> str:
"""
Friendly string name of the loaded OpenSSL library. This is not
necessarily the same version as it was compiled against.
Example: OpenSSL 3.2.1 30 Jan 2024
"""
return rust_openssl.openssl_version_text()
def openssl_version_number(self) -> int:
return rust_openssl.openssl_version()
def hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
if self._fips_enabled and not isinstance(algorithm, self._fips_hashes):
return False
return rust_openssl.hashes.hash_supported(algorithm)
def signature_hash_supported(
self, algorithm: hashes.HashAlgorithm
) -> bool:
# Dedicated check for hashing algorithm use in message digest for
# signatures, e.g. RSA PKCS#1 v1.5 SHA1 (sha1WithRSAEncryption).
if self._fips_enabled and isinstance(algorithm, hashes.SHA1):
return False
return self.hash_supported(algorithm)
def scrypt_supported(self) -> bool:
if self._fips_enabled:
return False
else:
return hasattr(rust_openssl.kdf.Scrypt, "derive")
def argon2_supported(self) -> bool:
if self._fips_enabled:
return False
else:
return hasattr(rust_openssl.kdf.Argon2id, "derive")
def hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
# FIPS mode still allows SHA1 for HMAC
if self._fips_enabled and isinstance(algorithm, hashes.SHA1):
return True
if rust_openssl.CRYPTOGRAPHY_IS_AWSLC:
return isinstance(
algorithm,
(
hashes.MD5,
hashes.SHA1,
hashes.SHA224,
hashes.SHA256,
hashes.SHA384,
hashes.SHA512,
hashes.SHA512_224,
hashes.SHA512_256,
),
)
return self.hash_supported(algorithm)
def cipher_supported(self, cipher: CipherAlgorithm, mode: Mode) -> bool:
if self._fips_enabled:
# FIPS mode requires AES. TripleDES is disallowed/deprecated in
# FIPS 140-3.
if not isinstance(cipher, self._fips_ciphers):
return False
return rust_openssl.ciphers.cipher_supported(cipher, mode)
def pbkdf2_hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
return self.hmac_supported(algorithm)
def _consume_errors(self) -> list[rust_openssl.OpenSSLError]:
return rust_openssl.capture_error_stack()
def _oaep_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
if self._fips_enabled and isinstance(algorithm, hashes.SHA1):
return False
return isinstance(
algorithm,
(
hashes.SHA1,
hashes.SHA224,
hashes.SHA256,
hashes.SHA384,
hashes.SHA512,
),
)
def rsa_padding_supported(self, padding: AsymmetricPadding) -> bool:
if isinstance(padding, PKCS1v15):
return True
elif isinstance(padding, PSS) and isinstance(padding._mgf, MGF1):
# FIPS 186-4 only allows salt length == digest length for PSS
# It is technically acceptable to set an explicit salt length
# equal to the digest length and this will incorrectly fail, but
# since we don't do that in the tests and this method is
# private, we'll ignore that until we need to do otherwise.
if (
self._fips_enabled
and padding._salt_length != PSS.DIGEST_LENGTH
):
return False
return self.hash_supported(padding._mgf._algorithm)
elif isinstance(padding, OAEP) and isinstance(padding._mgf, MGF1):
return self._oaep_hash_supported(
padding._mgf._algorithm
) and self._oaep_hash_supported(padding._algorithm)
else:
return False
def rsa_encryption_supported(self, padding: AsymmetricPadding) -> bool:
if self._fips_enabled and isinstance(padding, PKCS1v15):
return False
else:
return self.rsa_padding_supported(padding)
def dsa_supported(self) -> bool:
return (
not rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL
and not self._fips_enabled
)
def dsa_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
if not self.dsa_supported():
return False
return self.signature_hash_supported(algorithm)
def cmac_algorithm_supported(self, algorithm) -> bool:
return self.cipher_supported(
algorithm, CBC(b"\x00" * algorithm.block_size)
)
def elliptic_curve_supported(self, curve: ec.EllipticCurve) -> bool:
if self._fips_enabled and not isinstance(
curve, self._fips_ecdh_curves
):
return False
return rust_openssl.ec.curve_supported(curve)
def elliptic_curve_signature_algorithm_supported(
self,
signature_algorithm: ec.EllipticCurveSignatureAlgorithm,
curve: ec.EllipticCurve,
) -> bool:
# We only support ECDSA right now.
if not isinstance(signature_algorithm, ec.ECDSA):
return False
return self.elliptic_curve_supported(curve) and (
isinstance(signature_algorithm.algorithm, asym_utils.Prehashed)
or self.hash_supported(signature_algorithm.algorithm)
)
def elliptic_curve_exchange_algorithm_supported(
self, algorithm: ec.ECDH, curve: ec.EllipticCurve
) -> bool:
return self.elliptic_curve_supported(curve) and isinstance(
algorithm, ec.ECDH
)
def dh_supported(self) -> bool:
return (
not rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL
and not rust_openssl.CRYPTOGRAPHY_IS_AWSLC
)
def dh_x942_serialization_supported(self) -> bool:
return self._lib.Cryptography_HAS_EVP_PKEY_DHX == 1
def x25519_supported(self) -> bool:
return not self._fips_enabled
def x448_supported(self) -> bool:
if self._fips_enabled:
return False
return (
not rust_openssl.CRYPTOGRAPHY_IS_LIBRESSL
and not rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL
and not rust_openssl.CRYPTOGRAPHY_IS_AWSLC
)
def mlkem_supported(self) -> bool:
return (
rust_openssl.CRYPTOGRAPHY_IS_AWSLC
or rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL
or rust_openssl.CRYPTOGRAPHY_OPENSSL_350_OR_GREATER
)
def mldsa_supported(self) -> bool:
return (
rust_openssl.CRYPTOGRAPHY_IS_AWSLC
or rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL
or rust_openssl.CRYPTOGRAPHY_OPENSSL_350_OR_GREATER
)
def ed25519_supported(self) -> bool:
return True
def ed448_supported(self) -> bool:
return (
not rust_openssl.CRYPTOGRAPHY_IS_LIBRESSL
and not rust_openssl.CRYPTOGRAPHY_IS_BORINGSSL
and not rust_openssl.CRYPTOGRAPHY_IS_AWSLC
)
def ecdsa_deterministic_supported(self) -> bool:
return (
rust_openssl.CRYPTOGRAPHY_OPENSSL_320_OR_GREATER
and not self._fips_enabled
)
def poly1305_supported(self) -> bool:
if rust_openssl.CRYPTOGRAPHY_IS_AWSLC:
return True
return not self._fips_enabled
def pkcs7_supported(self) -> bool:
return True
backend = Backend()
@@ -0,0 +1,3 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
@@ -0,0 +1,67 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives._serialization import (
KeySerializationEncryptionBuilder,
)
from cryptography.utils import Buffer
class PKCS7PaddingContext(padding.PaddingContext):
def __init__(self, block_size: int) -> None: ...
def update(self, data: Buffer) -> bytes: ...
def finalize(self) -> bytes: ...
class ANSIX923PaddingContext(padding.PaddingContext):
def __init__(self, block_size: int) -> None: ...
def update(self, data: Buffer) -> bytes: ...
def finalize(self) -> bytes: ...
class PKCS7UnpaddingContext(padding.PaddingContext):
def __init__(self, block_size: int) -> None: ...
def update(self, data: Buffer) -> bytes: ...
def finalize(self) -> bytes: ...
class ANSIX923UnpaddingContext(padding.PaddingContext):
def __init__(self, block_size: int) -> None: ...
def update(self, data: Buffer) -> bytes: ...
def finalize(self) -> bytes: ...
class Encoding:
PEM: typing.ClassVar[Encoding]
DER: typing.ClassVar[Encoding]
OpenSSH: typing.ClassVar[Encoding]
Raw: typing.ClassVar[Encoding]
X962: typing.ClassVar[Encoding]
SMIME: typing.ClassVar[Encoding]
class PrivateFormat:
PKCS8: typing.ClassVar[PrivateFormat]
TraditionalOpenSSL: typing.ClassVar[PrivateFormat]
Raw: typing.ClassVar[PrivateFormat]
OpenSSH: typing.ClassVar[PrivateFormat]
PKCS12: typing.ClassVar[PrivateFormat]
def encryption_builder(self) -> KeySerializationEncryptionBuilder: ...
class PublicFormat:
SubjectPublicKeyInfo: typing.ClassVar[PublicFormat]
PKCS1: typing.ClassVar[PublicFormat]
OpenSSH: typing.ClassVar[PublicFormat]
Raw: typing.ClassVar[PublicFormat]
CompressedPoint: typing.ClassVar[PublicFormat]
UncompressedPoint: typing.ClassVar[PublicFormat]
class ParameterFormat:
PKCS3: typing.ClassVar[ParameterFormat]
class ObjectIdentifier:
def __init__(self, value: str) -> None: ...
@property
def dotted_string(self) -> str: ...
@property
def _name(self) -> str: ...
T = typing.TypeVar("T")
@@ -0,0 +1,8 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
lib: typing.Any
ffi: typing.Any
@@ -0,0 +1,7 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
def decode_dss_signature(signature: bytes) -> tuple[int, int]: ...
def encode_dss_signature(r: int, s: int) -> bytes: ...
def parse_spki_for_data(data: bytes) -> bytes: ...
@@ -0,0 +1,133 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import datetime
import typing
T = typing.TypeVar("T")
def decode_der(cls: type[T], value: bytes) -> T: ...
def encode_der(value: typing.Any) -> bytes: ...
def non_root_python_to_rust(cls: type) -> Type: ...
# Type is a Rust enum with tuple variants. For now, we express the type
# annotations like this:
class Type:
Sequence: typing.ClassVar[type]
SequenceOf: typing.ClassVar[type]
Set: typing.ClassVar[type]
SetOf: typing.ClassVar[type]
Option: typing.ClassVar[type]
Choice: typing.ClassVar[type]
ValueSet: typing.ClassVar[type]
PyBool: typing.ClassVar[type]
PyInt: typing.ClassVar[type]
PyBytes: typing.ClassVar[type]
PyStr: typing.ClassVar[type]
class Annotation:
default: typing.Any | None
encoding: Encoding | None
size: Size | None
def __new__(
cls,
default: typing.Any | None = None,
encoding: Encoding | None = None,
size: Size | None = None,
) -> Annotation: ...
def is_empty(self) -> bool: ...
# Encoding is a Rust enum with tuple variants. For now, we express the type
# annotations like this:
class Encoding:
Implicit: typing.ClassVar[type]
Explicit: typing.ClassVar[type]
class Size:
min: int
max: int | None
def __new__(cls, min: int, max: int | None) -> Size: ...
@staticmethod
def exact(n: int) -> Size: ...
class AnnotatedType:
inner: Type
annotation: Annotation
def __new__(cls, inner: Type, annotation: Annotation) -> AnnotatedType: ...
class AnnotatedTypeObject:
annotated_type: AnnotatedType
value: typing.Any
def __new__(
cls, annotated_type: AnnotatedType, value: typing.Any
) -> AnnotatedTypeObject: ...
class Variant:
python_class: type
ann_type: AnnotatedType
tag_name: str | None
def __new__(
cls,
python_class: type,
ann_type: AnnotatedType,
tag_name: str | None,
) -> Variant: ...
class PrintableString:
def __new__(cls, inner: str) -> PrintableString: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def as_str(self) -> str: ...
class IA5String:
def __new__(cls, inner: str) -> IA5String: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def as_str(self) -> str: ...
class UTCTime:
def __new__(cls, inner: datetime.datetime) -> UTCTime: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def as_datetime(self) -> datetime.datetime: ...
class GeneralizedTime:
def __new__(cls, inner: datetime.datetime) -> GeneralizedTime: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def as_datetime(self) -> datetime.datetime: ...
class BitString:
def __new__(cls, data: bytes, padding_bits: int) -> BitString: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def as_bytes(self) -> bytes: ...
def padding_bits(self) -> int: ...
class Tlv:
@property
def tag_bytes(self) -> bytes: ...
@property
def data(self) -> memoryview: ...
def parse(self, cls: type): ...
class SetOf(typing.Generic[T]):
def __new__(cls, inner: list[T]) -> SetOf[T]: ...
def as_list(self) -> list[T]: ...
def __eq__(self, other: object) -> bool: ...
def __repr__(self) -> str: ...
class Null:
def __new__(cls) -> Null: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
@@ -0,0 +1,17 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
class _Reasons:
BACKEND_MISSING_INTERFACE: _Reasons
UNSUPPORTED_HASH: _Reasons
UNSUPPORTED_CIPHER: _Reasons
UNSUPPORTED_PADDING: _Reasons
UNSUPPORTED_MGF: _Reasons
UNSUPPORTED_PUBLIC_KEY_ALGORITHM: _Reasons
UNSUPPORTED_ELLIPTIC_CURVE: _Reasons
UNSUPPORTED_SERIALIZATION: _Reasons
UNSUPPORTED_X509: _Reasons
UNSUPPORTED_EXCHANGE_ALGORITHM: _Reasons
UNSUPPORTED_DIFFIE_HELLMAN: _Reasons
UNSUPPORTED_MAC: _Reasons
@@ -0,0 +1,117 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import datetime
from collections.abc import Iterator
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
from cryptography.x509 import ocsp
class OCSPRequest:
@property
def issuer_key_hash(self) -> bytes: ...
@property
def issuer_name_hash(self) -> bytes: ...
@property
def hash_algorithm(self) -> hashes.HashAlgorithm: ...
@property
def serial_number(self) -> int: ...
def public_bytes(self, encoding: serialization.Encoding) -> bytes: ...
@property
def extensions(self) -> x509.Extensions: ...
class OCSPResponse:
@property
def responses(self) -> Iterator[OCSPSingleResponse]: ...
@property
def response_status(self) -> ocsp.OCSPResponseStatus: ...
@property
def signature_algorithm_oid(self) -> x509.ObjectIdentifier: ...
@property
def signature_hash_algorithm(
self,
) -> hashes.HashAlgorithm | None: ...
@property
def signature(self) -> bytes: ...
@property
def tbs_response_bytes(self) -> bytes: ...
@property
def certificates(self) -> list[x509.Certificate]: ...
@property
def responder_key_hash(self) -> bytes | None: ...
@property
def responder_name(self) -> x509.Name | None: ...
@property
def produced_at(self) -> datetime.datetime: ...
@property
def produced_at_utc(self) -> datetime.datetime: ...
@property
def certificate_status(self) -> ocsp.OCSPCertStatus: ...
@property
def revocation_time(self) -> datetime.datetime | None: ...
@property
def revocation_time_utc(self) -> datetime.datetime | None: ...
@property
def revocation_reason(self) -> x509.ReasonFlags | None: ...
@property
def this_update(self) -> datetime.datetime: ...
@property
def this_update_utc(self) -> datetime.datetime: ...
@property
def next_update(self) -> datetime.datetime | None: ...
@property
def next_update_utc(self) -> datetime.datetime | None: ...
@property
def issuer_key_hash(self) -> bytes: ...
@property
def issuer_name_hash(self) -> bytes: ...
@property
def hash_algorithm(self) -> hashes.HashAlgorithm: ...
@property
def serial_number(self) -> int: ...
@property
def extensions(self) -> x509.Extensions: ...
@property
def single_extensions(self) -> x509.Extensions: ...
def public_bytes(self, encoding: serialization.Encoding) -> bytes: ...
class OCSPSingleResponse:
@property
def certificate_status(self) -> ocsp.OCSPCertStatus: ...
@property
def revocation_time(self) -> datetime.datetime | None: ...
@property
def revocation_time_utc(self) -> datetime.datetime | None: ...
@property
def revocation_reason(self) -> x509.ReasonFlags | None: ...
@property
def this_update(self) -> datetime.datetime: ...
@property
def this_update_utc(self) -> datetime.datetime: ...
@property
def next_update(self) -> datetime.datetime | None: ...
@property
def next_update_utc(self) -> datetime.datetime | None: ...
@property
def issuer_key_hash(self) -> bytes: ...
@property
def issuer_name_hash(self) -> bytes: ...
@property
def hash_algorithm(self) -> hashes.HashAlgorithm: ...
@property
def serial_number(self) -> int: ...
def load_der_ocsp_request(data: bytes) -> ocsp.OCSPRequest: ...
def load_der_ocsp_response(data: bytes) -> ocsp.OCSPResponse: ...
def create_ocsp_request(
builder: ocsp.OCSPRequestBuilder,
) -> ocsp.OCSPRequest: ...
def create_ocsp_response(
status: ocsp.OCSPResponseStatus,
builder: ocsp.OCSPResponseBuilder | None,
private_key: PrivateKeyTypes | None,
hash_algorithm: hashes.HashAlgorithm | None,
) -> ocsp.OCSPResponse: ...
@@ -0,0 +1,80 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.bindings._rust.openssl import (
aead,
ciphers,
cmac,
dh,
dsa,
ec,
ed448,
ed25519,
hashes,
hmac,
hpke,
kdf,
keys,
mldsa,
mlkem,
poly1305,
rsa,
x448,
x25519,
)
__all__ = [
"aead",
"ciphers",
"cmac",
"dh",
"dsa",
"ec",
"ed448",
"ed25519",
"hashes",
"hmac",
"hpke",
"kdf",
"keys",
"mldsa",
"mlkem",
"openssl_version",
"openssl_version_text",
"poly1305",
"raise_openssl_error",
"rsa",
"x448",
"x25519",
]
CRYPTOGRAPHY_IS_LIBRESSL: bool
CRYPTOGRAPHY_IS_BORINGSSL: bool
CRYPTOGRAPHY_IS_AWSLC: bool
CRYPTOGRAPHY_OPENSSL_309_OR_GREATER: bool
CRYPTOGRAPHY_OPENSSL_320_OR_GREATER: bool
CRYPTOGRAPHY_OPENSSL_330_OR_GREATER: bool
CRYPTOGRAPHY_OPENSSL_350_OR_GREATER: bool
class Providers: ...
_legacy_provider_loaded: bool
_providers: Providers
def openssl_version() -> int: ...
def openssl_version_text() -> str: ...
def raise_openssl_error() -> typing.NoReturn: ...
def capture_error_stack() -> list[OpenSSLError]: ...
def is_fips_enabled() -> bool: ...
def enable_fips(providers: Providers) -> None: ...
class OpenSSLError:
@property
def lib(self) -> int: ...
@property
def reason(self) -> int: ...
@property
def reason_text(self) -> bytes: ...
@@ -0,0 +1,189 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from collections.abc import Sequence
from cryptography.utils import Buffer
class AESGCM:
def __init__(self, key: Buffer) -> None: ...
@staticmethod
def generate_key(bit_length: int) -> bytes: ...
def encrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def decrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def encrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
def decrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
class ChaCha20Poly1305:
def __init__(self, key: Buffer) -> None: ...
@staticmethod
def generate_key() -> bytes: ...
def encrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def encrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
def decrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def decrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
class AESCCM:
def __init__(self, key: Buffer, tag_length: int = 16) -> None: ...
@staticmethod
def generate_key(bit_length: int) -> bytes: ...
def encrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def encrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
def decrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def decrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
class AESSIV:
def __init__(self, key: Buffer) -> None: ...
@staticmethod
def generate_key(bit_length: int) -> bytes: ...
def encrypt(
self,
data: Buffer,
associated_data: Sequence[Buffer] | None,
) -> bytes: ...
def encrypt_into(
self,
data: Buffer,
associated_data: Sequence[Buffer] | None,
buf: Buffer,
) -> int: ...
def decrypt(
self,
data: Buffer,
associated_data: Sequence[Buffer] | None,
) -> bytes: ...
def decrypt_into(
self,
data: Buffer,
associated_data: Sequence[Buffer] | None,
buf: Buffer,
) -> int: ...
class AESOCB3:
def __init__(self, key: Buffer) -> None: ...
@staticmethod
def generate_key(bit_length: int) -> bytes: ...
def encrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def encrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
def decrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def decrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
class AESGCMSIV:
def __init__(self, key: Buffer) -> None: ...
@staticmethod
def generate_key(bit_length: int) -> bytes: ...
def encrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def encrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
def decrypt(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
) -> bytes: ...
def decrypt_into(
self,
nonce: Buffer,
data: Buffer,
associated_data: Buffer | None,
buf: Buffer,
) -> int: ...
@@ -0,0 +1,38 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives import ciphers
from cryptography.hazmat.primitives.ciphers import modes
@typing.overload
def create_encryption_ctx(
algorithm: ciphers.CipherAlgorithm, mode: modes.ModeWithAuthenticationTag
) -> ciphers.AEADEncryptionContext: ...
@typing.overload
def create_encryption_ctx(
algorithm: ciphers.CipherAlgorithm, mode: modes.Mode | None
) -> ciphers.CipherContext: ...
@typing.overload
def create_decryption_ctx(
algorithm: ciphers.CipherAlgorithm, mode: modes.ModeWithAuthenticationTag
) -> ciphers.AEADDecryptionContext: ...
@typing.overload
def create_decryption_ctx(
algorithm: ciphers.CipherAlgorithm, mode: modes.Mode | None
) -> ciphers.CipherContext: ...
def cipher_supported(
algorithm: ciphers.CipherAlgorithm, mode: modes.Mode
) -> bool: ...
def _advance(
ctx: ciphers.AEADEncryptionContext | ciphers.AEADDecryptionContext, n: int
) -> None: ...
def _advance_aad(
ctx: ciphers.AEADEncryptionContext | ciphers.AEADDecryptionContext, n: int
) -> None: ...
class CipherContext: ...
class AEADEncryptionContext: ...
class AEADDecryptionContext: ...
@@ -0,0 +1,18 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives import ciphers
class CMAC:
def __init__(
self,
algorithm: ciphers.BlockCipherAlgorithm,
backend: typing.Any = None,
) -> None: ...
def update(self, data: bytes) -> None: ...
def finalize(self) -> bytes: ...
def verify(self, signature: bytes) -> None: ...
def copy(self) -> CMAC: ...
@@ -0,0 +1,51 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives.asymmetric import dh
MIN_MODULUS_SIZE: int
class DHPrivateKey: ...
class DHPublicKey: ...
class DHParameters: ...
class DHPrivateNumbers:
def __init__(self, x: int, public_numbers: DHPublicNumbers) -> None: ...
def private_key(self, backend: typing.Any = None) -> dh.DHPrivateKey: ...
@property
def x(self) -> int: ...
@property
def public_numbers(self) -> DHPublicNumbers: ...
class DHPublicNumbers:
def __init__(
self, y: int, parameter_numbers: DHParameterNumbers
) -> None: ...
def public_key(self, backend: typing.Any = None) -> dh.DHPublicKey: ...
@property
def y(self) -> int: ...
@property
def parameter_numbers(self) -> DHParameterNumbers: ...
class DHParameterNumbers:
def __init__(self, p: int, g: int, q: int | None = None) -> None: ...
def parameters(self, backend: typing.Any = None) -> dh.DHParameters: ...
@property
def p(self) -> int: ...
@property
def g(self) -> int: ...
@property
def q(self) -> int | None: ...
def generate_parameters(
generator: int, key_size: int, backend: typing.Any = None
) -> dh.DHParameters: ...
def from_pem_parameters(
data: bytes, backend: typing.Any = None
) -> dh.DHParameters: ...
def from_der_parameters(
data: bytes, backend: typing.Any = None
) -> dh.DHParameters: ...
@@ -0,0 +1,41 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives.asymmetric import dsa
class DSAPrivateKey: ...
class DSAPublicKey: ...
class DSAParameters: ...
class DSAPrivateNumbers:
def __init__(self, x: int, public_numbers: DSAPublicNumbers) -> None: ...
@property
def x(self) -> int: ...
@property
def public_numbers(self) -> DSAPublicNumbers: ...
def private_key(self, backend: typing.Any = None) -> dsa.DSAPrivateKey: ...
class DSAPublicNumbers:
def __init__(
self, y: int, parameter_numbers: DSAParameterNumbers
) -> None: ...
@property
def y(self) -> int: ...
@property
def parameter_numbers(self) -> DSAParameterNumbers: ...
def public_key(self, backend: typing.Any = None) -> dsa.DSAPublicKey: ...
class DSAParameterNumbers:
def __init__(self, p: int, q: int, g: int) -> None: ...
@property
def p(self) -> int: ...
@property
def q(self) -> int: ...
@property
def g(self) -> int: ...
def parameters(self, backend: typing.Any = None) -> dsa.DSAParameters: ...
def generate_parameters(key_size: int) -> dsa.DSAParameters: ...
@@ -0,0 +1,52 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives.asymmetric import ec
class ECPrivateKey: ...
class ECPublicKey: ...
class EllipticCurvePrivateNumbers:
def __init__(
self, private_value: int, public_numbers: EllipticCurvePublicNumbers
) -> None: ...
def private_key(
self, backend: typing.Any = None
) -> ec.EllipticCurvePrivateKey: ...
@property
def private_value(self) -> int: ...
@property
def public_numbers(self) -> EllipticCurvePublicNumbers: ...
class EllipticCurvePublicNumbers:
def __init__(self, x: int, y: int, curve: ec.EllipticCurve) -> None: ...
def public_key(
self, backend: typing.Any = None
) -> ec.EllipticCurvePublicKey: ...
@property
def x(self) -> int: ...
@property
def y(self) -> int: ...
@property
def curve(self) -> ec.EllipticCurve: ...
def __eq__(self, other: object) -> bool: ...
def curve_supported(curve: ec.EllipticCurve) -> bool: ...
def generate_private_key(
curve: ec.EllipticCurve, backend: typing.Any = None
) -> ec.EllipticCurvePrivateKey: ...
def from_private_numbers(
numbers: ec.EllipticCurvePrivateNumbers,
) -> ec.EllipticCurvePrivateKey: ...
def from_public_numbers(
numbers: ec.EllipticCurvePublicNumbers,
) -> ec.EllipticCurvePublicKey: ...
def from_public_bytes(
curve: ec.EllipticCurve, data: bytes
) -> ec.EllipticCurvePublicKey: ...
def derive_private_key(
private_value: int, curve: ec.EllipticCurve
) -> ec.EllipticCurvePrivateKey: ...
@@ -0,0 +1,13 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.utils import Buffer
class Ed25519PrivateKey: ...
class Ed25519PublicKey: ...
def generate_key() -> ed25519.Ed25519PrivateKey: ...
def from_private_bytes(data: Buffer) -> ed25519.Ed25519PrivateKey: ...
def from_public_bytes(data: bytes) -> ed25519.Ed25519PublicKey: ...
@@ -0,0 +1,13 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.primitives.asymmetric import ed448
from cryptography.utils import Buffer
class Ed448PrivateKey: ...
class Ed448PublicKey: ...
def generate_key() -> ed448.Ed448PrivateKey: ...
def from_private_bytes(data: Buffer) -> ed448.Ed448PrivateKey: ...
def from_public_bytes(data: bytes) -> ed448.Ed448PublicKey: ...
@@ -0,0 +1,30 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives import hashes
from cryptography.utils import Buffer
class Hash(hashes.HashContext):
def __init__(
self, algorithm: hashes.HashAlgorithm, backend: typing.Any = None
) -> None: ...
@property
def algorithm(self) -> hashes.HashAlgorithm: ...
def update(self, data: Buffer) -> None: ...
def finalize(self) -> bytes: ...
def copy(self) -> Hash: ...
@staticmethod
def hash(algorithm: hashes.HashAlgorithm, data: Buffer) -> bytes: ...
def hash_supported(algorithm: hashes.HashAlgorithm) -> bool: ...
class XOFHash:
def __init__(self, algorithm: hashes.ExtendableOutputFunction) -> None: ...
@property
def algorithm(self) -> hashes.ExtendableOutputFunction: ...
def update(self, data: Buffer) -> None: ...
def squeeze(self, length: int) -> bytes: ...
def copy(self) -> XOFHash: ...
@@ -0,0 +1,22 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives import hashes
from cryptography.utils import Buffer
class HMAC(hashes.HashContext):
def __init__(
self,
key: Buffer,
algorithm: hashes.HashAlgorithm,
backend: typing.Any = None,
) -> None: ...
@property
def algorithm(self) -> hashes.HashAlgorithm: ...
def update(self, data: Buffer) -> None: ...
def finalize(self) -> bytes: ...
def verify(self, signature: bytes) -> None: ...
def copy(self) -> HMAC: ...
@@ -0,0 +1,109 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.primitives.asymmetric import ec, mlkem, x25519
from cryptography.utils import Buffer
class KEM:
X25519: KEM
P256: KEM
P384: KEM
P521: KEM
MLKEM768: KEM
MLKEM1024: KEM
MLKEM768_X25519: KEM
MLKEM1024_P384: KEM
def enc_length(self) -> int: ...
class KDF:
HKDF_SHA256: KDF
HKDF_SHA384: KDF
HKDF_SHA512: KDF
SHAKE128: KDF
SHAKE256: KDF
class AEAD:
AES_128_GCM: AEAD
AES_256_GCM: AEAD
CHACHA20_POLY1305: AEAD
class MLKEM768X25519PrivateKey:
def __init__(
self,
mlkem_key: mlkem.MLKEM768PrivateKey,
x25519_key: x25519.X25519PrivateKey,
) -> None: ...
def public_key(self) -> MLKEM768X25519PublicKey: ...
class MLKEM768X25519PublicKey:
def __init__(
self,
mlkem_key: mlkem.MLKEM768PublicKey,
x25519_key: x25519.X25519PublicKey,
) -> None: ...
class MLKEM1024P384PrivateKey:
def __init__(
self,
mlkem_key: mlkem.MLKEM1024PrivateKey,
p384_key: ec.EllipticCurvePrivateKey,
) -> None: ...
def public_key(self) -> MLKEM1024P384PublicKey: ...
class MLKEM1024P384PublicKey:
def __init__(
self,
mlkem_key: mlkem.MLKEM1024PublicKey,
p384_key: ec.EllipticCurvePublicKey,
) -> None: ...
class Suite:
def __init__(self, kem: KEM, kdf: KDF, aead: AEAD) -> None: ...
def encrypt(
self,
plaintext: Buffer,
public_key: x25519.X25519PublicKey
| ec.EllipticCurvePublicKey
| mlkem.MLKEM768PublicKey
| mlkem.MLKEM1024PublicKey
| MLKEM768X25519PublicKey
| MLKEM1024P384PublicKey,
info: Buffer | None = None,
) -> bytes: ...
def decrypt(
self,
ciphertext: Buffer,
private_key: x25519.X25519PrivateKey
| ec.EllipticCurvePrivateKey
| mlkem.MLKEM768PrivateKey
| mlkem.MLKEM1024PrivateKey
| MLKEM768X25519PrivateKey
| MLKEM1024P384PrivateKey,
info: Buffer | None = None,
) -> bytes: ...
def _encrypt_with_aad(
suite: Suite,
plaintext: Buffer,
public_key: x25519.X25519PublicKey
| ec.EllipticCurvePublicKey
| mlkem.MLKEM768PublicKey
| mlkem.MLKEM1024PublicKey
| MLKEM768X25519PublicKey
| MLKEM1024P384PublicKey,
info: Buffer | None = None,
aad: Buffer | None = None,
) -> bytes: ...
def _decrypt_with_aad(
suite: Suite,
ciphertext: Buffer,
private_key: x25519.X25519PrivateKey
| ec.EllipticCurvePrivateKey
| mlkem.MLKEM768PrivateKey
| mlkem.MLKEM1024PrivateKey
| MLKEM768X25519PrivateKey
| MLKEM1024P384PrivateKey,
info: Buffer | None = None,
aad: Buffer | None = None,
) -> bytes: ...
@@ -0,0 +1,205 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives.hashes import HashAlgorithm
from cryptography.hazmat.primitives.kdf.kbkdf import CounterLocation, Mode
from cryptography.utils import Buffer
class PBKDF2HMAC:
def __init__(
self,
algorithm: HashAlgorithm,
length: int,
salt: bytes,
iterations: int,
backend: typing.Any = None,
) -> None: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class Scrypt:
def __init__(
self,
salt: bytes,
length: int,
n: int,
r: int,
p: int,
backend: typing.Any = None,
) -> None: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class Argon2d:
def __init__(
self,
*,
salt: bytes,
length: int,
iterations: int,
lanes: int,
memory_cost: int,
ad: bytes | None = None,
secret: bytes | None = None,
) -> None: ...
def derive(self, key_material: bytes) -> bytes: ...
def derive_into(self, key_material: bytes, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
def derive_phc_encoded(self, key_material: bytes) -> str: ...
@classmethod
def verify_phc_encoded(
cls, key_material: bytes, phc_encoded: str, secret: bytes | None = None
) -> None: ...
class Argon2i:
def __init__(
self,
*,
salt: bytes,
length: int,
iterations: int,
lanes: int,
memory_cost: int,
ad: bytes | None = None,
secret: bytes | None = None,
) -> None: ...
def derive(self, key_material: bytes) -> bytes: ...
def derive_into(self, key_material: bytes, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
def derive_phc_encoded(self, key_material: bytes) -> str: ...
@classmethod
def verify_phc_encoded(
cls, key_material: bytes, phc_encoded: str, secret: bytes | None = None
) -> None: ...
class Argon2id:
def __init__(
self,
*,
salt: bytes,
length: int,
iterations: int,
lanes: int,
memory_cost: int,
ad: bytes | None = None,
secret: bytes | None = None,
) -> None: ...
def derive(self, key_material: bytes) -> bytes: ...
def derive_into(self, key_material: bytes, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
def derive_phc_encoded(self, key_material: bytes) -> str: ...
@classmethod
def verify_phc_encoded(
cls, key_material: bytes, phc_encoded: str, secret: bytes | None = None
) -> None: ...
class HKDF:
def __init__(
self,
algorithm: HashAlgorithm,
length: int,
salt: bytes | None,
info: bytes | None,
backend: typing.Any = None,
): ...
@staticmethod
def extract(
algorithm: HashAlgorithm, salt: bytes | None, key_material: Buffer
) -> bytes: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class HKDFExpand:
def __init__(
self,
algorithm: HashAlgorithm,
length: int,
info: bytes | None,
backend: typing.Any = None,
): ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class X963KDF:
def __init__(
self,
algorithm: HashAlgorithm,
length: int,
sharedinfo: bytes | None,
backend: typing.Any = None,
) -> None: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class ConcatKDFHash:
def __init__(
self,
algorithm: HashAlgorithm,
length: int,
otherinfo: bytes | None,
backend: typing.Any = None,
) -> None: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class ConcatKDFHMAC:
def __init__(
self,
algorithm: HashAlgorithm,
length: int,
salt: bytes | None,
otherinfo: bytes | None,
backend: typing.Any = None,
) -> None: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class KBKDFHMAC:
def __init__(
self,
algorithm: HashAlgorithm,
mode: Mode,
length: int,
rlen: int,
llen: int | None,
location: CounterLocation,
label: bytes | None,
context: bytes | None,
fixed: bytes | None,
backend: typing.Any = None,
*,
break_location: int | None = None,
) -> None: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
class KBKDFCMAC:
def __init__(
self,
algorithm: typing.Any,
mode: Mode,
length: int,
rlen: int,
llen: int | None,
location: CounterLocation,
label: bytes | None,
context: bytes | None,
fixed: bytes | None,
backend: typing.Any = None,
*,
break_location: int | None = None,
) -> None: ...
def derive(self, key_material: Buffer) -> bytes: ...
def derive_into(self, key_material: Buffer, buffer: Buffer) -> int: ...
def verify(self, key_material: bytes, expected_key: bytes) -> None: ...
@@ -0,0 +1,34 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives.asymmetric.types import (
PrivateKeyTypes,
PublicKeyTypes,
)
from cryptography.utils import Buffer
def load_der_private_key(
data: Buffer,
password: bytes | None,
backend: typing.Any = None,
*,
unsafe_skip_rsa_key_validation: bool = False,
) -> PrivateKeyTypes: ...
def load_pem_private_key(
data: Buffer,
password: bytes | None,
backend: typing.Any = None,
*,
unsafe_skip_rsa_key_validation: bool = False,
) -> PrivateKeyTypes: ...
def load_der_public_key(
data: bytes,
backend: typing.Any = None,
) -> PublicKeyTypes: ...
def load_pem_public_key(
data: bytes,
backend: typing.Any = None,
) -> PublicKeyTypes: ...
@@ -0,0 +1,23 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.primitives.asymmetric import mldsa
from cryptography.utils import Buffer
class MLDSA44PrivateKey: ...
class MLDSA44PublicKey: ...
class MLDSA65PrivateKey: ...
class MLDSA65PublicKey: ...
class MLDSA87PrivateKey: ...
class MLDSA87PublicKey: ...
def generate_mldsa44_key() -> mldsa.MLDSA44PrivateKey: ...
def from_mldsa44_public_bytes(data: bytes) -> mldsa.MLDSA44PublicKey: ...
def from_mldsa44_seed_bytes(data: Buffer) -> mldsa.MLDSA44PrivateKey: ...
def generate_mldsa65_key() -> mldsa.MLDSA65PrivateKey: ...
def from_mldsa65_public_bytes(data: bytes) -> mldsa.MLDSA65PublicKey: ...
def from_mldsa65_seed_bytes(data: Buffer) -> mldsa.MLDSA65PrivateKey: ...
def generate_mldsa87_key() -> mldsa.MLDSA87PrivateKey: ...
def from_mldsa87_public_bytes(data: bytes) -> mldsa.MLDSA87PublicKey: ...
def from_mldsa87_seed_bytes(data: Buffer) -> mldsa.MLDSA87PrivateKey: ...
@@ -0,0 +1,18 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.primitives.asymmetric import mlkem
from cryptography.utils import Buffer
class MLKEM768PrivateKey: ...
class MLKEM768PublicKey: ...
class MLKEM1024PrivateKey: ...
class MLKEM1024PublicKey: ...
def generate_mlkem768_key() -> mlkem.MLKEM768PrivateKey: ...
def from_mlkem768_seed_bytes(data: Buffer) -> mlkem.MLKEM768PrivateKey: ...
def from_mlkem768_public_bytes(data: Buffer) -> mlkem.MLKEM768PublicKey: ...
def generate_mlkem1024_key() -> mlkem.MLKEM1024PrivateKey: ...
def from_mlkem1024_seed_bytes(data: Buffer) -> mlkem.MLKEM1024PrivateKey: ...
def from_mlkem1024_public_bytes(data: Buffer) -> mlkem.MLKEM1024PublicKey: ...
@@ -0,0 +1,15 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.utils import Buffer
class Poly1305:
def __init__(self, key: Buffer) -> None: ...
@staticmethod
def generate_tag(key: Buffer, data: Buffer) -> bytes: ...
@staticmethod
def verify_tag(key: Buffer, data: Buffer, tag: bytes) -> None: ...
def update(self, data: Buffer) -> None: ...
def finalize(self) -> bytes: ...
def verify(self, tag: bytes) -> None: ...
@@ -0,0 +1,55 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from cryptography.hazmat.primitives.asymmetric import rsa
class RSAPrivateKey: ...
class RSAPublicKey: ...
class RSAPrivateNumbers:
def __init__(
self,
p: int,
q: int,
d: int,
dmp1: int,
dmq1: int,
iqmp: int,
public_numbers: RSAPublicNumbers,
) -> None: ...
@property
def p(self) -> int: ...
@property
def q(self) -> int: ...
@property
def d(self) -> int: ...
@property
def dmp1(self) -> int: ...
@property
def dmq1(self) -> int: ...
@property
def iqmp(self) -> int: ...
@property
def public_numbers(self) -> RSAPublicNumbers: ...
def private_key(
self,
backend: typing.Any = None,
*,
unsafe_skip_rsa_key_validation: bool = False,
) -> rsa.RSAPrivateKey: ...
class RSAPublicNumbers:
def __init__(self, e: int, n: int) -> None: ...
@property
def n(self) -> int: ...
@property
def e(self) -> int: ...
def public_key(self, backend: typing.Any = None) -> rsa.RSAPublicKey: ...
def generate_private_key(
public_exponent: int,
key_size: int,
) -> rsa.RSAPrivateKey: ...
@@ -0,0 +1,13 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.primitives.asymmetric import x25519
from cryptography.utils import Buffer
class X25519PrivateKey: ...
class X25519PublicKey: ...
def generate_key() -> x25519.X25519PrivateKey: ...
def from_private_bytes(data: Buffer) -> x25519.X25519PrivateKey: ...
def from_public_bytes(data: bytes) -> x25519.X25519PublicKey: ...
@@ -0,0 +1,13 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography.hazmat.primitives.asymmetric import x448
from cryptography.utils import Buffer
class X448PrivateKey: ...
class X448PublicKey: ...
def generate_key() -> x448.X448PrivateKey: ...
def from_private_bytes(data: Buffer) -> x448.X448PrivateKey: ...
def from_public_bytes(data: bytes) -> x448.X448PublicKey: ...
@@ -0,0 +1,52 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import typing
from collections.abc import Iterable
from cryptography import x509
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
from cryptography.hazmat.primitives.serialization import (
KeySerializationEncryption,
)
from cryptography.hazmat.primitives.serialization.pkcs12 import (
PKCS12KeyAndCertificates,
PKCS12PrivateKeyTypes,
)
from cryptography.utils import Buffer
class PKCS12Certificate:
def __init__(
self, cert: x509.Certificate, friendly_name: bytes | None
) -> None: ...
@property
def friendly_name(self) -> bytes | None: ...
@property
def certificate(self) -> x509.Certificate: ...
def load_key_and_certificates(
data: Buffer,
password: Buffer | None,
backend: typing.Any = None,
) -> tuple[
PrivateKeyTypes | None,
x509.Certificate | None,
list[x509.Certificate],
]: ...
def load_pkcs12(
data: bytes,
password: bytes | None,
backend: typing.Any = None,
) -> PKCS12KeyAndCertificates: ...
def serialize_java_truststore(
certs: Iterable[PKCS12Certificate],
encryption_algorithm: KeySerializationEncryption,
) -> bytes: ...
def serialize_key_and_certificates(
name: bytes | None,
key: PKCS12PrivateKeyTypes | None,
cert: x509.Certificate | None,
cas: Iterable[x509.Certificate | PKCS12Certificate] | None,
encryption_algorithm: KeySerializationEncryption,
) -> bytes: ...
@@ -0,0 +1,50 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from collections.abc import Iterable
from cryptography import x509
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import pkcs7
def serialize_certificates(
certs: list[x509.Certificate],
encoding: serialization.Encoding,
) -> bytes: ...
def encrypt_and_serialize(
builder: pkcs7.PKCS7EnvelopeBuilder,
content_encryption_algorithm: pkcs7.ContentEncryptionAlgorithm,
encoding: serialization.Encoding,
options: Iterable[pkcs7.PKCS7Options],
) -> bytes: ...
def sign_and_serialize(
builder: pkcs7.PKCS7SignatureBuilder,
encoding: serialization.Encoding,
options: Iterable[pkcs7.PKCS7Options],
) -> bytes: ...
def decrypt_der(
data: bytes,
certificate: x509.Certificate,
private_key: rsa.RSAPrivateKey,
options: Iterable[pkcs7.PKCS7Options],
) -> bytes: ...
def decrypt_pem(
data: bytes,
certificate: x509.Certificate,
private_key: rsa.RSAPrivateKey,
options: Iterable[pkcs7.PKCS7Options],
) -> bytes: ...
def decrypt_smime(
data: bytes,
certificate: x509.Certificate,
private_key: rsa.RSAPrivateKey,
options: Iterable[pkcs7.PKCS7Options],
) -> bytes: ...
def load_pem_pkcs7_certificates(
data: bytes,
) -> list[x509.Certificate]: ...
def load_der_pkcs7_certificates(
data: bytes,
) -> list[x509.Certificate]: ...
@@ -0,0 +1,23 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from cryptography import x509
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.serialization import pkcs7
from cryptography.utils import Buffer
class TestCertificate:
not_after_tag: int
not_before_tag: int
issuer_value_tags: list[int]
subject_value_tags: list[int]
def test_parse_certificate(data: bytes) -> TestCertificate: ...
def pkcs7_verify(
encoding: serialization.Encoding,
sig: bytes,
msg: Buffer | None,
certs: list[x509.Certificate],
options: list[pkcs7.PKCS7Options],
) -> None: ...
@@ -0,0 +1,313 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import datetime
import typing
from collections.abc import Iterator
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric.ec import ECDSA
from cryptography.hazmat.primitives.asymmetric.padding import PSS, PKCS1v15
from cryptography.hazmat.primitives.asymmetric.types import (
CertificateIssuerPublicKeyTypes,
CertificatePublicKeyTypes,
PrivateKeyTypes,
)
from cryptography.x509 import certificate_transparency
def load_pem_x509_certificate(
data: bytes, backend: typing.Any = None
) -> x509.Certificate: ...
def load_der_x509_certificate(
data: bytes, backend: typing.Any = None
) -> x509.Certificate: ...
def load_pem_x509_certificates(
data: bytes,
) -> list[x509.Certificate]: ...
def load_pem_x509_crl(
data: bytes, backend: typing.Any = None
) -> x509.CertificateRevocationList: ...
def load_der_x509_crl(
data: bytes, backend: typing.Any = None
) -> x509.CertificateRevocationList: ...
def load_pem_x509_csr(
data: bytes, backend: typing.Any = None
) -> x509.CertificateSigningRequest: ...
def load_der_x509_csr(
data: bytes, backend: typing.Any = None
) -> x509.CertificateSigningRequest: ...
def encode_name_bytes(name: x509.Name) -> bytes: ...
def parse_name_bytes(data: bytes) -> x509.Name: ...
def encode_extension_value(extension: x509.ExtensionType) -> bytes: ...
def create_x509_certificate(
builder: x509.CertificateBuilder,
private_key: PrivateKeyTypes,
hash_algorithm: hashes.HashAlgorithm | None,
rsa_padding: PKCS1v15 | PSS | None,
ecdsa_deterministic: bool | None,
) -> x509.Certificate: ...
def create_x509_csr(
builder: x509.CertificateSigningRequestBuilder,
private_key: PrivateKeyTypes,
hash_algorithm: hashes.HashAlgorithm | None,
rsa_padding: PKCS1v15 | PSS | None,
ecdsa_deterministic: bool | None,
) -> x509.CertificateSigningRequest: ...
def create_revoked_certificate(
builder: x509.RevokedCertificateBuilder,
) -> x509.RevokedCertificate: ...
def create_x509_crl(
builder: x509.CertificateRevocationListBuilder,
private_key: PrivateKeyTypes,
hash_algorithm: hashes.HashAlgorithm | None,
rsa_padding: PKCS1v15 | PSS | None,
ecdsa_deterministic: bool | None,
) -> x509.CertificateRevocationList: ...
class Sct:
@property
def version(self) -> certificate_transparency.Version: ...
@property
def log_id(self) -> bytes: ...
@property
def timestamp(self) -> datetime.datetime: ...
@property
def entry_type(self) -> certificate_transparency.LogEntryType: ...
@property
def signature_hash_algorithm(self) -> hashes.HashAlgorithm: ...
@property
def signature_algorithm(
self,
) -> certificate_transparency.SignatureAlgorithm: ...
@property
def signature(self) -> bytes: ...
@property
def extension_bytes(self) -> bytes: ...
class Certificate:
def fingerprint(self, algorithm: hashes.HashAlgorithm) -> bytes: ...
@property
def serial_number(self) -> int: ...
@property
def version(self) -> x509.Version: ...
def public_key(self) -> CertificatePublicKeyTypes: ...
@property
def public_key_algorithm_oid(self) -> x509.ObjectIdentifier: ...
@property
def not_valid_before(self) -> datetime.datetime: ...
@property
def not_valid_before_utc(self) -> datetime.datetime: ...
@property
def not_valid_after(self) -> datetime.datetime: ...
@property
def not_valid_after_utc(self) -> datetime.datetime: ...
@property
def issuer(self) -> x509.Name: ...
@property
def subject(self) -> x509.Name: ...
@property
def signature_hash_algorithm(
self,
) -> hashes.HashAlgorithm | None: ...
@property
def signature_algorithm_oid(self) -> x509.ObjectIdentifier: ...
@property
def signature_algorithm_parameters(
self,
) -> PSS | PKCS1v15 | ECDSA | None: ...
@property
def extensions(self) -> x509.Extensions: ...
@property
def signature(self) -> bytes: ...
@property
def tbs_certificate_bytes(self) -> bytes: ...
@property
def tbs_precertificate_bytes(self) -> bytes: ...
def __eq__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def public_bytes(self, encoding: serialization.Encoding) -> bytes: ...
def verify_directly_issued_by(self, issuer: Certificate) -> None: ...
class RevokedCertificate:
@property
def serial_number(self) -> int: ...
@property
def revocation_date(self) -> datetime.datetime: ...
@property
def revocation_date_utc(self) -> datetime.datetime: ...
@property
def extensions(self) -> x509.Extensions: ...
class CertificateRevocationList:
def public_bytes(self, encoding: serialization.Encoding) -> bytes: ...
def fingerprint(self, algorithm: hashes.HashAlgorithm) -> bytes: ...
def get_revoked_certificate_by_serial_number(
self, serial_number: int
) -> x509.RevokedCertificate | None: ...
@property
def signature_hash_algorithm(
self,
) -> hashes.HashAlgorithm | None: ...
@property
def signature_algorithm_oid(self) -> x509.ObjectIdentifier: ...
@property
def signature_algorithm_parameters(
self,
) -> PSS | PKCS1v15 | ECDSA | None: ...
@property
def issuer(self) -> x509.Name: ...
@property
def next_update(self) -> datetime.datetime | None: ...
@property
def next_update_utc(self) -> datetime.datetime | None: ...
@property
def last_update(self) -> datetime.datetime: ...
@property
def last_update_utc(self) -> datetime.datetime: ...
@property
def extensions(self) -> x509.Extensions: ...
@property
def signature(self) -> bytes: ...
@property
def tbs_certlist_bytes(self) -> bytes: ...
def __eq__(self, other: object) -> bool: ...
def __len__(self) -> int: ...
@typing.overload
def __getitem__(self, idx: int) -> x509.RevokedCertificate: ...
@typing.overload
def __getitem__(self, idx: slice) -> list[x509.RevokedCertificate]: ...
def __iter__(self) -> Iterator[x509.RevokedCertificate]: ...
def is_signature_valid(
self, public_key: CertificateIssuerPublicKeyTypes
) -> bool: ...
class CertificateSigningRequest:
def __eq__(self, other: object) -> bool: ...
def __hash__(self) -> int: ...
def public_key(self) -> CertificatePublicKeyTypes: ...
@property
def subject(self) -> x509.Name: ...
@property
def signature_hash_algorithm(
self,
) -> hashes.HashAlgorithm | None: ...
@property
def signature_algorithm_oid(self) -> x509.ObjectIdentifier: ...
@property
def signature_algorithm_parameters(
self,
) -> PSS | PKCS1v15 | ECDSA | None: ...
@property
def extensions(self) -> x509.Extensions: ...
@property
def attributes(self) -> x509.Attributes: ...
def public_bytes(self, encoding: serialization.Encoding) -> bytes: ...
@property
def signature(self) -> bytes: ...
@property
def tbs_certrequest_bytes(self) -> bytes: ...
@property
def is_signature_valid(self) -> bool: ...
class PolicyBuilder:
def time(self, time: datetime.datetime) -> PolicyBuilder: ...
def store(self, store: Store) -> PolicyBuilder: ...
def max_chain_depth(self, max_chain_depth: int) -> PolicyBuilder: ...
def extension_policies(
self, *, ca_policy: ExtensionPolicy, ee_policy: ExtensionPolicy
) -> PolicyBuilder: ...
def build_client_verifier(self) -> ClientVerifier: ...
def build_server_verifier(
self, subject: x509.verification.Subject
) -> ServerVerifier: ...
class Policy:
@property
def max_chain_depth(self) -> int: ...
@property
def subject(self) -> x509.verification.Subject | None: ...
@property
def validation_time(self) -> datetime.datetime: ...
@property
def extended_key_usage(self) -> x509.ObjectIdentifier: ...
@property
def minimum_rsa_modulus(self) -> int: ...
class Criticality:
CRITICAL: Criticality
AGNOSTIC: Criticality
NON_CRITICAL: Criticality
T = typing.TypeVar("T", contravariant=True, bound=x509.ExtensionType)
MaybeExtensionValidatorCallback = typing.Callable[
[
Policy,
x509.Certificate,
T | None,
],
None,
]
PresentExtensionValidatorCallback = typing.Callable[
[Policy, x509.Certificate, T],
None,
]
class ExtensionPolicy:
@staticmethod
def permit_all() -> ExtensionPolicy: ...
@staticmethod
def webpki_defaults_ca() -> ExtensionPolicy: ...
@staticmethod
def webpki_defaults_ee() -> ExtensionPolicy: ...
def require_not_present(
self, extension_type: type[x509.ExtensionType]
) -> ExtensionPolicy: ...
def may_be_present(
self,
extension_type: type[T],
criticality: Criticality,
validator: MaybeExtensionValidatorCallback[T] | None,
) -> ExtensionPolicy: ...
def require_present(
self,
extension_type: type[T],
criticality: Criticality,
validator: PresentExtensionValidatorCallback[T] | None,
) -> ExtensionPolicy: ...
class VerifiedClient:
@property
def subjects(self) -> list[x509.GeneralName] | None: ...
@property
def chain(self) -> list[x509.Certificate]: ...
class ClientVerifier:
@property
def policy(self) -> Policy: ...
@property
def store(self) -> Store: ...
def verify(
self,
leaf: x509.Certificate,
intermediates: list[x509.Certificate],
) -> VerifiedClient: ...
class ServerVerifier:
@property
def policy(self) -> Policy: ...
@property
def store(self) -> Store: ...
def verify(
self,
leaf: x509.Certificate,
intermediates: list[x509.Certificate],
) -> list[x509.Certificate]: ...
class Store:
def __init__(self, certs: list[x509.Certificate]) -> None: ...
class VerificationError(Exception): ...
@@ -0,0 +1,3 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
@@ -0,0 +1,199 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
def cryptography_has_set_cert_cb() -> list[str]:
return [
"SSL_CTX_set_cert_cb",
"SSL_set_cert_cb",
]
def cryptography_has_ssl_st() -> list[str]:
return [
"SSL_ST_BEFORE",
"SSL_ST_OK",
"SSL_ST_INIT",
"SSL_ST_RENEGOTIATE",
]
def cryptography_has_tls_st() -> list[str]:
return [
"TLS_ST_BEFORE",
"TLS_ST_OK",
]
def cryptography_has_ssl_sigalgs() -> list[str]:
return [
"SSL_CTX_set1_sigalgs_list",
]
def cryptography_has_psk() -> list[str]:
return [
"SSL_CTX_use_psk_identity_hint",
"SSL_CTX_set_psk_server_callback",
"SSL_CTX_set_psk_client_callback",
]
def cryptography_has_psk_tlsv13() -> list[str]:
return [
"SSL_CTX_set_psk_find_session_callback",
"SSL_CTX_set_psk_use_session_callback",
"Cryptography_SSL_SESSION_new",
"SSL_CIPHER_find",
"SSL_SESSION_set1_master_key",
"SSL_SESSION_set_cipher",
"SSL_SESSION_set_protocol_version",
]
def cryptography_has_custom_ext() -> list[str]:
return [
"SSL_CTX_add_client_custom_ext",
"SSL_CTX_add_server_custom_ext",
"SSL_extension_supported",
]
def cryptography_has_tlsv13_functions() -> list[str]:
return [
"SSL_CTX_set_ciphersuites",
]
def cryptography_has_tlsv13_hs_functions() -> list[str]:
return [
"SSL_VERIFY_POST_HANDSHAKE",
"SSL_verify_client_post_handshake",
"SSL_CTX_set_post_handshake_auth",
"SSL_set_post_handshake_auth",
"SSL_SESSION_get_max_early_data",
"SSL_write_early_data",
"SSL_read_early_data",
"SSL_CTX_set_max_early_data",
]
def cryptography_has_ssl_verify_client_post_handshake() -> list[str]:
return [
"SSL_verify_client_post_handshake",
]
def cryptography_has_engine() -> list[str]:
return [
"ENGINE_by_id",
"ENGINE_init",
"ENGINE_finish",
"ENGINE_get_default_RAND",
"ENGINE_set_default_RAND",
"ENGINE_unregister_RAND",
"ENGINE_ctrl_cmd",
"ENGINE_free",
"ENGINE_get_name",
"ENGINE_ctrl_cmd_string",
"ENGINE_load_builtin_engines",
"ENGINE_load_private_key",
"ENGINE_load_public_key",
"SSL_CTX_set_client_cert_engine",
]
def cryptography_has_verified_chain() -> list[str]:
return [
"SSL_get0_verified_chain",
]
def cryptography_has_srtp() -> list[str]:
return [
"SSL_CTX_set_tlsext_use_srtp",
"SSL_set_tlsext_use_srtp",
"SSL_get_selected_srtp_profile",
]
def cryptography_has_dtls_get_data_mtu() -> list[str]:
return [
"DTLS_get_data_mtu",
]
def cryptography_has_ssl_cookie() -> list[str]:
return [
"SSL_OP_COOKIE_EXCHANGE",
"DTLS1_COOKIE_LENGTH",
"DTLSv1_listen",
"SSL_CTX_set_cookie_generate_cb",
"SSL_CTX_set_cookie_verify_cb",
]
def cryptography_has_prime_checks() -> list[str]:
return [
"BN_prime_checks_for_size",
]
def cryptography_has_unexpected_eof_while_reading() -> list[str]:
return ["SSL_R_UNEXPECTED_EOF_WHILE_READING"]
def cryptography_has_ssl_op_ignore_unexpected_eof() -> list[str]:
return [
"SSL_OP_IGNORE_UNEXPECTED_EOF",
]
def cryptography_has_get_extms_support() -> list[str]:
return ["SSL_get_extms_support"]
def cryptography_has_ssl_get0_group_name() -> list[str]:
return ["SSL_get0_group_name"]
# This is a mapping of
# {condition: function-returning-names-dependent-on-that-condition} so we can
# loop over them and delete unsupported names at runtime. It will be removed
# when cffi supports #if in cdef. We use functions instead of just a dict of
# lists so we can use coverage to measure which are used.
CONDITIONAL_NAMES = {
"Cryptography_HAS_SET_CERT_CB": cryptography_has_set_cert_cb,
"Cryptography_HAS_SSL_ST": cryptography_has_ssl_st,
"Cryptography_HAS_TLS_ST": cryptography_has_tls_st,
"Cryptography_HAS_SIGALGS": cryptography_has_ssl_sigalgs,
"Cryptography_HAS_PSK": cryptography_has_psk,
"Cryptography_HAS_PSK_TLSv1_3": cryptography_has_psk_tlsv13,
"Cryptography_HAS_CUSTOM_EXT": cryptography_has_custom_ext,
"Cryptography_HAS_TLSv1_3_FUNCTIONS": cryptography_has_tlsv13_functions,
"Cryptography_HAS_TLSv1_3_HS_FUNCTIONS": (
cryptography_has_tlsv13_hs_functions
),
"Cryptography_HAS_SSL_VERIFY_CLIENT_POST_HANDSHAKE": (
cryptography_has_ssl_verify_client_post_handshake
),
"Cryptography_HAS_ENGINE": cryptography_has_engine,
"Cryptography_HAS_VERIFIED_CHAIN": cryptography_has_verified_chain,
"Cryptography_HAS_SRTP": cryptography_has_srtp,
"Cryptography_HAS_DTLS_GET_DATA_MTU": cryptography_has_dtls_get_data_mtu,
"Cryptography_HAS_SSL_COOKIE": cryptography_has_ssl_cookie,
"Cryptography_HAS_PRIME_CHECKS": cryptography_has_prime_checks,
"Cryptography_HAS_UNEXPECTED_EOF_WHILE_READING": (
cryptography_has_unexpected_eof_while_reading
),
"Cryptography_HAS_SSL_OP_IGNORE_UNEXPECTED_EOF": (
cryptography_has_ssl_op_ignore_unexpected_eof
),
"Cryptography_HAS_GET_EXTMS_SUPPORT": cryptography_has_get_extms_support,
"Cryptography_HAS_SSL_GET0_GROUP_NAME": (
cryptography_has_ssl_get0_group_name
),
}
@@ -0,0 +1,107 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import threading
import types
import typing
from collections.abc import Callable, Mapping
import cryptography
from cryptography.exceptions import InternalError
from cryptography.hazmat.bindings._rust import _openssl, openssl
from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES
def _openssl_assert(ok: bool) -> None:
if not ok:
errors = openssl.capture_error_stack()
raise InternalError(
"Unknown OpenSSL error. This error is commonly encountered when "
"another library is not cleaning up the OpenSSL error stack. If "
"you are using cryptography with another library that uses "
"OpenSSL try disabling it before reporting a bug. Otherwise "
"please file an issue at https://github.com/pyca/cryptography/"
"issues with information on how to reproduce "
f"this. ({errors!r})",
errors,
)
def build_conditional_library(
lib: typing.Any,
conditional_names: Mapping[str, Callable[[], list[str]]],
) -> typing.Any:
conditional_lib = types.ModuleType("lib")
conditional_lib._original_lib = lib # type: ignore[attr-defined]
excluded_names = set()
for condition, names_cb in conditional_names.items():
if not getattr(lib, condition):
excluded_names.update(names_cb())
for attr in dir(lib):
if attr not in excluded_names:
setattr(conditional_lib, attr, getattr(lib, attr))
return conditional_lib
class Binding:
"""
OpenSSL API wrapper.
"""
lib: typing.ClassVar[typing.Any] = None
ffi: typing.Any = _openssl.ffi
_lib_loaded = False
_init_lock = threading.Lock()
def __init__(self) -> None:
self._ensure_ffi_initialized()
@classmethod
def _ensure_ffi_initialized(cls) -> None:
with cls._init_lock:
if not cls._lib_loaded:
cls.lib = build_conditional_library(
_openssl.lib, CONDITIONAL_NAMES
)
cls._lib_loaded = True
@classmethod
def init_static_locks(cls) -> None:
cls._ensure_ffi_initialized()
def _verify_package_version(version: str) -> None:
# Occasionally we run into situations where the version of the Python
# package does not match the version of the shared object that is loaded.
# This may occur in environments where multiple versions of cryptography
# are installed and available in the python path. To avoid errors cropping
# up later this code checks that the currently imported package and the
# shared object that were loaded have the same version and raise an
# ImportError if they do not
so_package_version = _openssl.ffi.string(
_openssl.lib.CRYPTOGRAPHY_PACKAGE_VERSION
)
if version.encode("ascii") != so_package_version:
raise ImportError(
"The version of cryptography does not match the loaded "
"shared object. This can happen if you have multiple copies of "
"cryptography installed in your Python path. Please try creating "
"a new virtual environment to resolve this issue. "
f"Loaded python version: {version}, "
f"shared object version: {so_package_version}"
)
_openssl_assert(
_openssl.lib.OpenSSL_version_num() == openssl.openssl_version(),
)
_verify_package_version(cryptography.__version__)
Binding.init_static_locks()
@@ -0,0 +1,5 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
@@ -0,0 +1,5 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
@@ -0,0 +1,142 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import warnings
from cryptography import utils
from cryptography.hazmat.primitives._cipheralgorithm import (
BlockCipherAlgorithm,
CipherAlgorithm,
_verify_key_size,
)
class ARC4(CipherAlgorithm):
name = "RC4"
key_sizes = frozenset([40, 56, 64, 80, 128, 160, 192, 256])
def __init__(self, key: bytes):
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
class TripleDES(BlockCipherAlgorithm):
name = "3DES"
block_size = 64
key_sizes = frozenset([64, 128, 192])
def __init__(self, key: bytes):
if len(key) == 8:
warnings.warn(
"Single-key TripleDES (8-byte keys) is deprecated and "
"support will be removed in a future release. Use 24-byte "
"keys instead (e.g., key + key + key).",
utils.DeprecatedIn47,
stacklevel=2,
)
key = key + key + key
elif len(key) == 16:
warnings.warn(
"Two-key TripleDES (16-byte keys) is deprecated and "
"support will be removed in a future release. Use 24-byte "
"keys instead (e.g., key + key[:8]).",
utils.DeprecatedIn47,
stacklevel=2,
)
key = key + key[:8]
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
# Not actually supported, marker for tests
class _DES:
key_size = 64
class Blowfish(BlockCipherAlgorithm):
name = "Blowfish"
block_size = 64
key_sizes = frozenset(range(32, 449, 8))
def __init__(self, key: bytes):
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
class CAST5(BlockCipherAlgorithm):
name = "CAST5"
block_size = 64
key_sizes = frozenset(range(40, 129, 8))
def __init__(self, key: bytes):
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
class SEED(BlockCipherAlgorithm):
name = "SEED"
block_size = 128
key_sizes = frozenset([128])
def __init__(self, key: bytes):
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
class IDEA(BlockCipherAlgorithm):
name = "IDEA"
block_size = 64
key_sizes = frozenset([128])
def __init__(self, key: bytes):
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
class Camellia(BlockCipherAlgorithm):
name = "camellia"
block_size = 128
key_sizes = frozenset([128, 192, 256])
def __init__(self, key: bytes):
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
# This class only allows RC2 with a 128-bit key. No support for
# effective key bits or other key sizes is provided.
class RC2(BlockCipherAlgorithm):
name = "RC2"
block_size = 64
key_sizes = frozenset([128])
def __init__(self, key: bytes):
self.key = _verify_key_size(self, key)
@property
def key_size(self) -> int:
return len(self.key) * 8
@@ -0,0 +1,53 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
from cryptography import utils
from cryptography.hazmat.primitives._modes import (
ModeWithInitializationVector,
_check_iv_and_key_length,
)
class OFB(ModeWithInitializationVector):
name = "OFB"
def __init__(self, initialization_vector: utils.Buffer):
utils._check_byteslike("initialization_vector", initialization_vector)
self._initialization_vector = initialization_vector
@property
def initialization_vector(self) -> utils.Buffer:
return self._initialization_vector
validate_for_algorithm = _check_iv_and_key_length
class CFB(ModeWithInitializationVector):
name = "CFB"
def __init__(self, initialization_vector: utils.Buffer):
utils._check_byteslike("initialization_vector", initialization_vector)
self._initialization_vector = initialization_vector
@property
def initialization_vector(self) -> utils.Buffer:
return self._initialization_vector
validate_for_algorithm = _check_iv_and_key_length
class CFB8(ModeWithInitializationVector):
name = "CFB8"
def __init__(self, initialization_vector: utils.Buffer):
utils._check_byteslike("initialization_vector", initialization_vector)
self._initialization_vector = initialization_vector
@property
def initialization_vector(self) -> utils.Buffer:
return self._initialization_vector
validate_for_algorithm = _check_iv_and_key_length
@@ -0,0 +1,3 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
@@ -0,0 +1,19 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
# This exists to break an import cycle. It is normally accessible from the
# asymmetric padding module.
class AsymmetricPadding(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def name(self) -> str:
"""
A string naming this padding (e.g. "PSS", "PKCS1").
"""
@@ -0,0 +1,60 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
from cryptography import utils
# This exists to break an import cycle. It is normally accessible from the
# ciphers module.
class CipherAlgorithm(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def name(self) -> str:
"""
A string naming this mode (e.g. "AES", "Camellia").
"""
@property
@abc.abstractmethod
def key_sizes(self) -> frozenset[int]:
"""
Valid key sizes for this algorithm in bits
"""
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
The size of the key being used as an integer in bits (e.g. 128, 256).
"""
class BlockCipherAlgorithm(CipherAlgorithm):
key: utils.Buffer
@property
@abc.abstractmethod
def block_size(self) -> int:
"""
The size of a block as an integer in bits (e.g. 64, 128).
"""
def _verify_key_size(
algorithm: CipherAlgorithm, key: utils.Buffer
) -> utils.Buffer:
# Verify that the key is instance of bytes
utils._check_byteslike("key", key)
# Verify that the key size matches the expected key size
if len(key) * 8 not in algorithm.key_sizes:
raise ValueError(
f"Invalid key size ({len(key) * 8}) for {algorithm.name}."
)
return key
@@ -0,0 +1,105 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
from cryptography import utils
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
from cryptography.hazmat.primitives._cipheralgorithm import (
BlockCipherAlgorithm,
CipherAlgorithm,
)
class Mode(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def name(self) -> str:
"""
A string naming this mode (e.g. "ECB", "CBC").
"""
@abc.abstractmethod
def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None:
"""
Checks that all the necessary invariants of this (mode, algorithm)
combination are met.
"""
class ModeWithInitializationVector(Mode, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def initialization_vector(self) -> utils.Buffer:
"""
The value of the initialization vector for this mode as bytes.
"""
class ModeWithTweak(Mode, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def tweak(self) -> utils.Buffer:
"""
The value of the tweak for this mode as bytes.
"""
class ModeWithNonce(Mode, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def nonce(self) -> utils.Buffer:
"""
The value of the nonce for this mode as bytes.
"""
class ModeWithAuthenticationTag(Mode, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def tag(self) -> bytes | None:
"""
The value of the tag supplied to the constructor of this mode.
"""
def _check_aes_key_length(self: Mode, algorithm: CipherAlgorithm) -> None:
if algorithm.key_size > 256 and algorithm.name == "AES":
raise ValueError(
"Only 128, 192, and 256 bit keys are allowed for this AES mode"
)
def _check_iv_length(
self: ModeWithInitializationVector, algorithm: BlockCipherAlgorithm
) -> None:
iv_len = len(self.initialization_vector)
if iv_len * 8 != algorithm.block_size:
raise ValueError(f"Invalid IV size ({iv_len}) for {self.name}.")
def _check_nonce_length(
nonce: utils.Buffer, name: str, algorithm: CipherAlgorithm
) -> None:
if not isinstance(algorithm, BlockCipherAlgorithm):
raise UnsupportedAlgorithm(
f"{name} requires a block cipher algorithm",
_Reasons.UNSUPPORTED_CIPHER,
)
if len(nonce) * 8 != algorithm.block_size:
raise ValueError(f"Invalid nonce size ({len(nonce)}) for {name}.")
def _check_iv_and_key_length(
self: ModeWithInitializationVector, algorithm: CipherAlgorithm
) -> None:
if not isinstance(algorithm, BlockCipherAlgorithm):
raise UnsupportedAlgorithm(
f"{self} requires a block cipher algorithm",
_Reasons.UNSUPPORTED_CIPHER,
)
_check_aes_key_length(self, algorithm)
_check_iv_length(self, algorithm)
@@ -0,0 +1,136 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
from cryptography import utils
from cryptography.hazmat.bindings._rust import Encoding as Encoding
from cryptography.hazmat.bindings._rust import (
ParameterFormat as ParameterFormat,
)
from cryptography.hazmat.bindings._rust import PrivateFormat as PrivateFormat
from cryptography.hazmat.bindings._rust import PublicFormat as PublicFormat
from cryptography.hazmat.primitives.hashes import HashAlgorithm
# This exists to break an import cycle. These classes are normally accessible
# from the serialization module.
class PBES(utils.Enum):
PBESv1SHA1And3KeyTripleDESCBC = "PBESv1 using SHA1 and 3-Key TripleDES"
PBESv2SHA256AndAES256CBC = "PBESv2 using SHA256 PBKDF2 and AES256 CBC"
class KeySerializationEncryption(metaclass=abc.ABCMeta):
pass
class BestAvailableEncryption(KeySerializationEncryption):
def __init__(self, password: bytes):
if not isinstance(password, bytes) or len(password) == 0:
raise ValueError("Password must be 1 or more bytes.")
self.password = password
class NoEncryption(KeySerializationEncryption):
pass
class KeySerializationEncryptionBuilder:
def __init__(
self,
format: PrivateFormat,
*,
_kdf_rounds: int | None = None,
_hmac_hash: HashAlgorithm | None = None,
_key_cert_algorithm: PBES | None = None,
) -> None:
self._format = format
self._kdf_rounds = _kdf_rounds
self._hmac_hash = _hmac_hash
self._key_cert_algorithm = _key_cert_algorithm
def kdf_rounds(self, rounds: int) -> KeySerializationEncryptionBuilder:
if self._kdf_rounds is not None:
raise ValueError("kdf_rounds already set")
if not isinstance(rounds, int):
raise TypeError("kdf_rounds must be an integer")
if rounds < 1:
raise ValueError("kdf_rounds must be a positive integer")
return KeySerializationEncryptionBuilder(
self._format,
_kdf_rounds=rounds,
_hmac_hash=self._hmac_hash,
_key_cert_algorithm=self._key_cert_algorithm,
)
def hmac_hash(
self, algorithm: HashAlgorithm
) -> KeySerializationEncryptionBuilder:
if self._format is not PrivateFormat.PKCS12:
raise TypeError(
"hmac_hash only supported with PrivateFormat.PKCS12"
)
if self._hmac_hash is not None:
raise ValueError("hmac_hash already set")
return KeySerializationEncryptionBuilder(
self._format,
_kdf_rounds=self._kdf_rounds,
_hmac_hash=algorithm,
_key_cert_algorithm=self._key_cert_algorithm,
)
def key_cert_algorithm(
self, algorithm: PBES
) -> KeySerializationEncryptionBuilder:
if self._format is not PrivateFormat.PKCS12:
raise TypeError(
"key_cert_algorithm only supported with PrivateFormat.PKCS12"
)
if self._key_cert_algorithm is not None:
raise ValueError("key_cert_algorithm already set")
return KeySerializationEncryptionBuilder(
self._format,
_kdf_rounds=self._kdf_rounds,
_hmac_hash=self._hmac_hash,
_key_cert_algorithm=algorithm,
)
def build(self, password: bytes) -> KeySerializationEncryption:
if not isinstance(password, bytes) or len(password) == 0:
raise ValueError("Password must be 1 or more bytes.")
return _KeySerializationEncryption(
self._format,
password,
kdf_rounds=self._kdf_rounds,
hmac_hash=self._hmac_hash,
key_cert_algorithm=self._key_cert_algorithm,
)
class _KeySerializationEncryption(KeySerializationEncryption):
def __init__(
self,
format: PrivateFormat,
password: bytes,
*,
kdf_rounds: int | None,
hmac_hash: HashAlgorithm | None,
key_cert_algorithm: PBES | None,
):
self._format = format
self.password = password
self._kdf_rounds = kdf_rounds
self._hmac_hash = hmac_hash
self._key_cert_algorithm = key_cert_algorithm
@@ -0,0 +1,3 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
@@ -0,0 +1,159 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.primitives import _serialization
generate_parameters = rust_openssl.dh.generate_parameters
DHPrivateNumbers = rust_openssl.dh.DHPrivateNumbers
DHPublicNumbers = rust_openssl.dh.DHPublicNumbers
DHParameterNumbers = rust_openssl.dh.DHParameterNumbers
class DHParameters(metaclass=abc.ABCMeta):
@abc.abstractmethod
def generate_private_key(self) -> DHPrivateKey:
"""
Generates and returns a DHPrivateKey.
"""
@abc.abstractmethod
def parameter_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.ParameterFormat,
) -> bytes:
"""
Returns the parameters serialized as bytes.
"""
@abc.abstractmethod
def parameter_numbers(self) -> DHParameterNumbers:
"""
Returns a DHParameterNumbers.
"""
DHParametersWithSerialization = DHParameters
DHParameters.register(rust_openssl.dh.DHParameters)
class DHPublicKey(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
The bit length of the prime modulus.
"""
@abc.abstractmethod
def parameters(self) -> DHParameters:
"""
The DHParameters object associated with this public key.
"""
@abc.abstractmethod
def public_numbers(self) -> DHPublicNumbers:
"""
Returns a DHPublicNumbers.
"""
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> DHPublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> DHPublicKey:
"""
Returns a deep copy.
"""
DHPublicKeyWithSerialization = DHPublicKey
DHPublicKey.register(rust_openssl.dh.DHPublicKey)
class DHPrivateKey(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
The bit length of the prime modulus.
"""
@abc.abstractmethod
def public_key(self) -> DHPublicKey:
"""
The DHPublicKey associated with this private key.
"""
@abc.abstractmethod
def parameters(self) -> DHParameters:
"""
The DHParameters object associated with this private key.
"""
@abc.abstractmethod
def exchange(self, peer_public_key: DHPublicKey) -> bytes:
"""
Given peer's DHPublicKey, carry out the key exchange and
return shared key as bytes.
"""
@abc.abstractmethod
def private_numbers(self) -> DHPrivateNumbers:
"""
Returns a DHPrivateNumbers.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
@abc.abstractmethod
def __copy__(self) -> DHPrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> DHPrivateKey:
"""
Returns a deep copy.
"""
DHPrivateKeyWithSerialization = DHPrivateKey
DHPrivateKey.register(rust_openssl.dh.DHPrivateKey)
@@ -0,0 +1,179 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
import typing
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.primitives import _serialization, hashes
from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
from cryptography.utils import Buffer
class DSAParameters(metaclass=abc.ABCMeta):
@abc.abstractmethod
def generate_private_key(self) -> DSAPrivateKey:
"""
Generates and returns a DSAPrivateKey.
"""
@abc.abstractmethod
def parameter_numbers(self) -> DSAParameterNumbers:
"""
Returns a DSAParameterNumbers.
"""
DSAParametersWithNumbers = DSAParameters
DSAParameters.register(rust_openssl.dsa.DSAParameters)
class DSAPrivateKey(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
The bit length of the prime modulus.
"""
@abc.abstractmethod
def public_key(self) -> DSAPublicKey:
"""
The DSAPublicKey associated with this private key.
"""
@abc.abstractmethod
def parameters(self) -> DSAParameters:
"""
The DSAParameters object associated with this private key.
"""
@abc.abstractmethod
def sign(
self,
data: Buffer,
algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
) -> bytes:
"""
Signs the data
"""
@abc.abstractmethod
def private_numbers(self) -> DSAPrivateNumbers:
"""
Returns a DSAPrivateNumbers.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
@abc.abstractmethod
def __copy__(self) -> DSAPrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> DSAPrivateKey:
"""
Returns a deep copy.
"""
DSAPrivateKeyWithSerialization = DSAPrivateKey
DSAPrivateKey.register(rust_openssl.dsa.DSAPrivateKey)
class DSAPublicKey(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
The bit length of the prime modulus.
"""
@abc.abstractmethod
def parameters(self) -> DSAParameters:
"""
The DSAParameters object associated with this public key.
"""
@abc.abstractmethod
def public_numbers(self) -> DSAPublicNumbers:
"""
Returns a DSAPublicNumbers.
"""
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
@abc.abstractmethod
def verify(
self,
signature: Buffer,
data: Buffer,
algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
) -> None:
"""
Verifies the signature of the data.
"""
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> DSAPublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> DSAPublicKey:
"""
Returns a deep copy.
"""
DSAPublicKeyWithSerialization = DSAPublicKey
DSAPublicKey.register(rust_openssl.dsa.DSAPublicKey)
DSAPrivateNumbers = rust_openssl.dsa.DSAPrivateNumbers
DSAPublicNumbers = rust_openssl.dsa.DSAPublicNumbers
DSAParameterNumbers = rust_openssl.dsa.DSAParameterNumbers
def generate_parameters(
key_size: int, backend: typing.Any = None
) -> DSAParameters:
if key_size not in (1024, 2048, 3072, 4096):
raise ValueError("Key size must be 1024, 2048, 3072, or 4096 bits.")
return rust_openssl.dsa.generate_parameters(key_size)
def generate_private_key(
key_size: int, backend: typing.Any = None
) -> DSAPrivateKey:
parameters = generate_parameters(key_size)
return parameters.generate_private_key()
@@ -0,0 +1,369 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
import typing
from cryptography import utils
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
from cryptography.hazmat._oid import ObjectIdentifier
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.primitives import _serialization, hashes
from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
class EllipticCurveOID:
SECP192R1 = ObjectIdentifier("1.2.840.10045.3.1.1")
SECP224R1 = ObjectIdentifier("1.3.132.0.33")
SECP256K1 = ObjectIdentifier("1.3.132.0.10")
SECP256R1 = ObjectIdentifier("1.2.840.10045.3.1.7")
SECP384R1 = ObjectIdentifier("1.3.132.0.34")
SECP521R1 = ObjectIdentifier("1.3.132.0.35")
BRAINPOOLP256R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.7")
BRAINPOOLP384R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.11")
BRAINPOOLP512R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.13")
class EllipticCurve(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def name(self) -> str:
"""
The name of the curve. e.g. secp256r1.
"""
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
Bit size of a secret scalar for the curve.
"""
@property
@abc.abstractmethod
def group_order(self) -> int:
"""
The order of the curve's group.
"""
class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def algorithm(
self,
) -> asym_utils.Prehashed | hashes.HashAlgorithm:
"""
The digest algorithm used with this signature.
"""
class EllipticCurvePrivateKey(metaclass=abc.ABCMeta):
@abc.abstractmethod
def exchange(
self, algorithm: ECDH, peer_public_key: EllipticCurvePublicKey
) -> bytes:
"""
Performs a key exchange operation using the provided algorithm with the
provided peer's public key.
"""
@abc.abstractmethod
def public_key(self) -> EllipticCurvePublicKey:
"""
The EllipticCurvePublicKey for this private key.
"""
@property
@abc.abstractmethod
def curve(self) -> EllipticCurve:
"""
The EllipticCurve that this key is on.
"""
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
Bit size of a secret scalar for the curve.
"""
@abc.abstractmethod
def sign(
self,
data: utils.Buffer,
signature_algorithm: EllipticCurveSignatureAlgorithm,
) -> bytes:
"""
Signs the data
"""
@abc.abstractmethod
def private_numbers(self) -> EllipticCurvePrivateNumbers:
"""
Returns an EllipticCurvePrivateNumbers.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
@abc.abstractmethod
def __copy__(self) -> EllipticCurvePrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> EllipticCurvePrivateKey:
"""
Returns a deep copy.
"""
EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey
EllipticCurvePrivateKey.register(rust_openssl.ec.ECPrivateKey)
class EllipticCurvePublicKey(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def curve(self) -> EllipticCurve:
"""
The EllipticCurve that this key is on.
"""
@property
@abc.abstractmethod
def key_size(self) -> int:
"""
Bit size of a secret scalar for the curve.
"""
@abc.abstractmethod
def public_numbers(self) -> EllipticCurvePublicNumbers:
"""
Returns an EllipticCurvePublicNumbers.
"""
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
@abc.abstractmethod
def verify(
self,
signature: utils.Buffer,
data: utils.Buffer,
signature_algorithm: EllipticCurveSignatureAlgorithm,
) -> None:
"""
Verifies the signature of the data.
"""
@classmethod
def from_encoded_point(
cls, curve: EllipticCurve, data: bytes
) -> EllipticCurvePublicKey:
utils._check_bytes("data", data)
if len(data) == 0:
raise ValueError("data must not be an empty byte string")
if data[0] not in [0x02, 0x03, 0x04]:
raise ValueError("Unsupported elliptic curve point type")
return rust_openssl.ec.from_public_bytes(curve, data)
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> EllipticCurvePublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> EllipticCurvePublicKey:
"""
Returns a deep copy.
"""
EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey
EllipticCurvePublicKey.register(rust_openssl.ec.ECPublicKey)
EllipticCurvePrivateNumbers = rust_openssl.ec.EllipticCurvePrivateNumbers
EllipticCurvePublicNumbers = rust_openssl.ec.EllipticCurvePublicNumbers
class SECP521R1(EllipticCurve):
name = "secp521r1"
key_size = 521
group_order = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409 # noqa: E501
class SECP384R1(EllipticCurve):
name = "secp384r1"
key_size = 384
group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973 # noqa: E501
class SECP256R1(EllipticCurve):
name = "secp256r1"
key_size = 256
group_order = (
0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551
)
class SECP256K1(EllipticCurve):
name = "secp256k1"
key_size = 256
group_order = (
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
)
class SECP224R1(EllipticCurve):
name = "secp224r1"
key_size = 224
group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D
class SECP192R1(EllipticCurve):
name = "secp192r1"
key_size = 192
group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831
class BrainpoolP256R1(EllipticCurve):
name = "brainpoolP256r1"
key_size = 256
group_order = (
0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
)
class BrainpoolP384R1(EllipticCurve):
name = "brainpoolP384r1"
key_size = 384
group_order = 0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565 # noqa: E501
class BrainpoolP512R1(EllipticCurve):
name = "brainpoolP512r1"
key_size = 512
group_order = 0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069 # noqa: E501
_CURVE_TYPES: dict[str, EllipticCurve] = {
"prime192v1": SECP192R1(),
"prime256v1": SECP256R1(),
"secp192r1": SECP192R1(),
"secp224r1": SECP224R1(),
"secp256r1": SECP256R1(),
"secp384r1": SECP384R1(),
"secp521r1": SECP521R1(),
"secp256k1": SECP256K1(),
"brainpoolP256r1": BrainpoolP256R1(),
"brainpoolP384r1": BrainpoolP384R1(),
"brainpoolP512r1": BrainpoolP512R1(),
}
class ECDSA(EllipticCurveSignatureAlgorithm):
def __init__(
self,
algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,
deterministic_signing: bool = False,
):
from cryptography.hazmat.backends.openssl.backend import backend
if (
deterministic_signing
and not backend.ecdsa_deterministic_supported()
):
raise UnsupportedAlgorithm(
"ECDSA with deterministic signature (RFC 6979) is not "
"supported by this version of OpenSSL.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
self._algorithm = algorithm
self._deterministic_signing = deterministic_signing
@property
def algorithm(
self,
) -> asym_utils.Prehashed | hashes.HashAlgorithm:
return self._algorithm
@property
def deterministic_signing(
self,
) -> bool:
return self._deterministic_signing
generate_private_key = rust_openssl.ec.generate_private_key
def derive_private_key(
private_value: int,
curve: EllipticCurve,
backend: typing.Any = None,
) -> EllipticCurvePrivateKey:
if not isinstance(private_value, int):
raise TypeError("private_value must be an integer type.")
if private_value <= 0:
raise ValueError("private_value must be a positive integer.")
return rust_openssl.ec.derive_private_key(private_value, curve)
class ECDH:
pass
_OID_TO_CURVE = {
EllipticCurveOID.SECP192R1: SECP192R1,
EllipticCurveOID.SECP224R1: SECP224R1,
EllipticCurveOID.SECP256K1: SECP256K1,
EllipticCurveOID.SECP256R1: SECP256R1,
EllipticCurveOID.SECP384R1: SECP384R1,
EllipticCurveOID.SECP521R1: SECP521R1,
EllipticCurveOID.BRAINPOOLP256R1: BrainpoolP256R1,
EllipticCurveOID.BRAINPOOLP384R1: BrainpoolP384R1,
EllipticCurveOID.BRAINPOOLP512R1: BrainpoolP512R1,
}
def get_curve_for_oid(oid: ObjectIdentifier) -> type[EllipticCurve]:
try:
return _OID_TO_CURVE[oid]
except KeyError:
raise LookupError(
"The provided object identifier has no matching elliptic "
"curve class"
)
@@ -0,0 +1,116 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.primitives import _serialization
from cryptography.utils import Buffer
class Ed25519PublicKey(metaclass=abc.ABCMeta):
@classmethod
def from_public_bytes(cls, data: bytes) -> Ed25519PublicKey:
return rust_openssl.ed25519.from_public_bytes(data)
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
The serialized bytes of the public key.
"""
@abc.abstractmethod
def public_bytes_raw(self) -> bytes:
"""
The raw bytes of the public key.
Equivalent to public_bytes(Raw, Raw).
"""
@abc.abstractmethod
def verify(self, signature: Buffer, data: Buffer) -> None:
"""
Verify the signature.
"""
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> Ed25519PublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> Ed25519PublicKey:
"""
Returns a deep copy.
"""
Ed25519PublicKey.register(rust_openssl.ed25519.Ed25519PublicKey)
class Ed25519PrivateKey(metaclass=abc.ABCMeta):
@classmethod
def generate(cls) -> Ed25519PrivateKey:
return rust_openssl.ed25519.generate_key()
@classmethod
def from_private_bytes(cls, data: Buffer) -> Ed25519PrivateKey:
return rust_openssl.ed25519.from_private_bytes(data)
@abc.abstractmethod
def public_key(self) -> Ed25519PublicKey:
"""
The Ed25519PublicKey derived from the private key.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
The serialized bytes of the private key.
"""
@abc.abstractmethod
def private_bytes_raw(self) -> bytes:
"""
The raw bytes of the private key.
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
"""
@abc.abstractmethod
def sign(self, data: Buffer) -> bytes:
"""
Signs the data.
"""
@abc.abstractmethod
def __copy__(self) -> Ed25519PrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> Ed25519PrivateKey:
"""
Returns a deep copy.
"""
Ed25519PrivateKey.register(rust_openssl.ed25519.Ed25519PrivateKey)
@@ -0,0 +1,143 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.primitives import _serialization
from cryptography.utils import Buffer
class Ed448PublicKey(metaclass=abc.ABCMeta):
@classmethod
def from_public_bytes(cls, data: bytes) -> Ed448PublicKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.ed448_supported():
raise UnsupportedAlgorithm(
"ed448 is not supported by this version of OpenSSL.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.ed448.from_public_bytes(data)
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
The serialized bytes of the public key.
"""
@abc.abstractmethod
def public_bytes_raw(self) -> bytes:
"""
The raw bytes of the public key.
Equivalent to public_bytes(Raw, Raw).
"""
@abc.abstractmethod
def verify(self, signature: Buffer, data: Buffer) -> None:
"""
Verify the signature.
"""
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> Ed448PublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> Ed448PublicKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "ed448"):
Ed448PublicKey.register(rust_openssl.ed448.Ed448PublicKey)
class Ed448PrivateKey(metaclass=abc.ABCMeta):
@classmethod
def generate(cls) -> Ed448PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.ed448_supported():
raise UnsupportedAlgorithm(
"ed448 is not supported by this version of OpenSSL.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.ed448.generate_key()
@classmethod
def from_private_bytes(cls, data: Buffer) -> Ed448PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.ed448_supported():
raise UnsupportedAlgorithm(
"ed448 is not supported by this version of OpenSSL.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.ed448.from_private_bytes(data)
@abc.abstractmethod
def public_key(self) -> Ed448PublicKey:
"""
The Ed448PublicKey derived from the private key.
"""
@abc.abstractmethod
def sign(self, data: Buffer) -> bytes:
"""
Signs the data.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
The serialized bytes of the private key.
"""
@abc.abstractmethod
def private_bytes_raw(self) -> bytes:
"""
The raw bytes of the private key.
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
"""
@abc.abstractmethod
def __copy__(self) -> Ed448PrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> Ed448PrivateKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "x448"):
Ed448PrivateKey.register(rust_openssl.ed448.Ed448PrivateKey)
@@ -0,0 +1,504 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import annotations
import abc
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.primitives import _serialization
from cryptography.utils import Buffer
class MLDSA44PublicKey(metaclass=abc.ABCMeta):
@classmethod
def from_public_bytes(cls, data: bytes) -> MLDSA44PublicKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-44 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.from_mldsa44_public_bytes(data)
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
The serialized bytes of the public key.
"""
@abc.abstractmethod
def public_bytes_raw(self) -> bytes:
"""
The raw bytes of the public key.
Equivalent to public_bytes(Raw, Raw).
The public key is 1,312 bytes for MLDSA-44.
"""
@abc.abstractmethod
def verify(
self,
signature: Buffer,
data: Buffer,
context: Buffer | None = None,
) -> None:
"""
Verify the signature.
"""
@abc.abstractmethod
def verify_mu(
self,
signature: Buffer,
mu: Buffer,
) -> None:
"""
Verify the signature over a precomputed mu (message representative).
mu must be 64 bytes.
"""
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> MLDSA44PublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> MLDSA44PublicKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "mldsa"):
MLDSA44PublicKey.register(rust_openssl.mldsa.MLDSA44PublicKey)
class MLDSA44PrivateKey(metaclass=abc.ABCMeta):
@classmethod
def generate(cls) -> MLDSA44PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-44 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.generate_mldsa44_key()
@classmethod
def from_seed_bytes(cls, data: Buffer) -> MLDSA44PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-44 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.from_mldsa44_seed_bytes(data)
@abc.abstractmethod
def public_key(self) -> MLDSA44PublicKey:
"""
The MLDSA44PublicKey derived from the private key.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
The serialized bytes of the private key.
This method only returns the serialization of the seed form of the
private key, never the expanded one.
"""
@abc.abstractmethod
def private_bytes_raw(self) -> bytes:
"""
The raw bytes of the private key.
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
This method only returns the seed form of the private key (32 bytes).
"""
@abc.abstractmethod
def sign(self, data: Buffer, context: Buffer | None = None) -> bytes:
"""
Signs the data.
"""
@abc.abstractmethod
def sign_mu(self, mu: Buffer) -> bytes:
"""
Signs a precomputed mu (message representative).
mu must be 64 bytes and already incorporates the context, so no
context is accepted here.
"""
@abc.abstractmethod
def __copy__(self) -> MLDSA44PrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> MLDSA44PrivateKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "mldsa"):
MLDSA44PrivateKey.register(rust_openssl.mldsa.MLDSA44PrivateKey)
class MLDSA65PublicKey(metaclass=abc.ABCMeta):
@classmethod
def from_public_bytes(cls, data: bytes) -> MLDSA65PublicKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-65 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.from_mldsa65_public_bytes(data)
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
The serialized bytes of the public key.
"""
@abc.abstractmethod
def public_bytes_raw(self) -> bytes:
"""
The raw bytes of the public key.
Equivalent to public_bytes(Raw, Raw).
The public key is 1,952 bytes for MLDSA-65.
"""
@abc.abstractmethod
def verify(
self,
signature: Buffer,
data: Buffer,
context: Buffer | None = None,
) -> None:
"""
Verify the signature.
"""
@abc.abstractmethod
def verify_mu(
self,
signature: Buffer,
mu: Buffer,
) -> None:
"""
Verify the signature over a precomputed mu (message representative).
mu must be 64 bytes.
"""
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> MLDSA65PublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> MLDSA65PublicKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "mldsa"):
MLDSA65PublicKey.register(rust_openssl.mldsa.MLDSA65PublicKey)
class MLDSA65PrivateKey(metaclass=abc.ABCMeta):
@classmethod
def generate(cls) -> MLDSA65PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-65 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.generate_mldsa65_key()
@classmethod
def from_seed_bytes(cls, data: Buffer) -> MLDSA65PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-65 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.from_mldsa65_seed_bytes(data)
@abc.abstractmethod
def public_key(self) -> MLDSA65PublicKey:
"""
The MLDSA65PublicKey derived from the private key.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
The serialized bytes of the private key.
This method only returns the serialization of the seed form of the
private key, never the expanded one.
"""
@abc.abstractmethod
def private_bytes_raw(self) -> bytes:
"""
The raw bytes of the private key.
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
This method only returns the seed form of the private key (32 bytes).
"""
@abc.abstractmethod
def sign(self, data: Buffer, context: Buffer | None = None) -> bytes:
"""
Signs the data.
"""
@abc.abstractmethod
def sign_mu(self, mu: Buffer) -> bytes:
"""
Signs a precomputed mu (message representative).
mu must be 64 bytes and already incorporates the context, so no
context is accepted here.
"""
@abc.abstractmethod
def __copy__(self) -> MLDSA65PrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> MLDSA65PrivateKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "mldsa"):
MLDSA65PrivateKey.register(rust_openssl.mldsa.MLDSA65PrivateKey)
class MLDSA87PublicKey(metaclass=abc.ABCMeta):
@classmethod
def from_public_bytes(cls, data: bytes) -> MLDSA87PublicKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-87 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.from_mldsa87_public_bytes(data)
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
The serialized bytes of the public key.
"""
@abc.abstractmethod
def public_bytes_raw(self) -> bytes:
"""
The raw bytes of the public key.
Equivalent to public_bytes(Raw, Raw).
The public key is 2,592 bytes for MLDSA-87.
"""
@abc.abstractmethod
def verify(
self,
signature: Buffer,
data: Buffer,
context: Buffer | None = None,
) -> None:
"""
Verify the signature.
"""
@abc.abstractmethod
def verify_mu(
self,
signature: Buffer,
mu: Buffer,
) -> None:
"""
Verify the signature over a precomputed mu (message representative).
mu must be 64 bytes.
"""
@abc.abstractmethod
def __eq__(self, other: object) -> bool:
"""
Checks equality.
"""
@abc.abstractmethod
def __copy__(self) -> MLDSA87PublicKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> MLDSA87PublicKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "mldsa"):
MLDSA87PublicKey.register(rust_openssl.mldsa.MLDSA87PublicKey)
class MLDSA87PrivateKey(metaclass=abc.ABCMeta):
@classmethod
def generate(cls) -> MLDSA87PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-87 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.generate_mldsa87_key()
@classmethod
def from_seed_bytes(cls, data: Buffer) -> MLDSA87PrivateKey:
from cryptography.hazmat.backends.openssl.backend import backend
if not backend.mldsa_supported():
raise UnsupportedAlgorithm(
"ML-DSA-87 is not supported by this backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,
)
return rust_openssl.mldsa.from_mldsa87_seed_bytes(data)
@abc.abstractmethod
def public_key(self) -> MLDSA87PublicKey:
"""
The MLDSA87PublicKey derived from the private key.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
The serialized bytes of the private key.
This method only returns the serialization of the seed form of the
private key, never the expanded one.
"""
@abc.abstractmethod
def private_bytes_raw(self) -> bytes:
"""
The raw bytes of the private key.
Equivalent to private_bytes(Raw, Raw, NoEncryption()).
This method only returns the seed form of the private key (32 bytes).
"""
@abc.abstractmethod
def sign(self, data: Buffer, context: Buffer | None = None) -> bytes:
"""
Signs the data.
"""
@abc.abstractmethod
def sign_mu(self, mu: Buffer) -> bytes:
"""
Signs a precomputed mu (message representative).
mu must be 64 bytes and already incorporates the context, so no
context is accepted here.
"""
@abc.abstractmethod
def __copy__(self) -> MLDSA87PrivateKey:
"""
Returns a copy.
"""
@abc.abstractmethod
def __deepcopy__(self, memo: dict) -> MLDSA87PrivateKey:
"""
Returns a deep copy.
"""
if hasattr(rust_openssl, "mldsa"):
MLDSA87PrivateKey.register(rust_openssl.mldsa.MLDSA87PrivateKey)

Some files were not shown because too many files have changed in this diff Show More