python-pkcs11 0.9.2__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ def biginteger(value):
2
+ """
3
+ Returns a PKCS#11 biginteger bytestream from a Python integer or
4
+ similar type (e.g. :class:`asn1crypto.core.Integer`).
5
+
6
+ :param int value: Value
7
+ :rtype: bytes
8
+ """
9
+
10
+ value = int(value) # In case it's a asn1 type or similar
11
+
12
+ return value.to_bytes((value.bit_length() + 7) // 8, byteorder="big")
pkcs11/util/dh.py ADDED
@@ -0,0 +1,72 @@
1
+ """
2
+ Key handling utilities for Diffie-Hellman keys.
3
+ """
4
+
5
+ from asn1crypto.algos import DHParameters
6
+ from asn1crypto.core import Integer
7
+
8
+ from pkcs11.constants import Attribute
9
+ from pkcs11.util import biginteger
10
+
11
+
12
+ def decode_dh_domain_parameters(der):
13
+ """
14
+ Decode DER-encoded Diffie-Hellman domain parameters.
15
+
16
+ :param bytes der: DER-encoded parameters
17
+ :rtype: dict(Attribute,*)
18
+ """
19
+
20
+ params = DHParameters.load(der)
21
+
22
+ return {
23
+ Attribute.BASE: biginteger(params["g"]),
24
+ Attribute.PRIME: biginteger(params["p"]),
25
+ }
26
+
27
+
28
+ def encode_dh_domain_parameters(obj):
29
+ """
30
+ Encode DH domain parameters into DER-encoded format.
31
+
32
+ Calculates the subprime if it isn't available.
33
+
34
+ :param DomainParameters obj: domain parameters
35
+ :rtype: bytes
36
+ """
37
+
38
+ asn1 = DHParameters(
39
+ {
40
+ "g": int.from_bytes(obj[Attribute.BASE], byteorder="big"),
41
+ "p": int.from_bytes(obj[Attribute.PRIME], byteorder="big"),
42
+ }
43
+ )
44
+
45
+ return asn1.dump()
46
+
47
+
48
+ def encode_dh_public_key(key):
49
+ """
50
+ Encode DH public key into RFC 3279 DER-encoded format.
51
+
52
+ :param PublicKey key: public key
53
+ :rtype: bytes
54
+ """
55
+
56
+ asn1 = Integer(int.from_bytes(key[Attribute.VALUE], byteorder="big"))
57
+
58
+ return asn1.dump()
59
+
60
+
61
+ def decode_dh_public_key(der):
62
+ """
63
+ Decode a DH public key from RFC 3279 DER-encoded format.
64
+
65
+ Returns a `biginteger` encoded as bytes.
66
+
67
+ :param bytes der: DER-encoded public key
68
+ :rtype: bytes
69
+ """
70
+
71
+ asn1 = Integer.load(der)
72
+ return biginteger(asn1)
pkcs11/util/dsa.py ADDED
@@ -0,0 +1,101 @@
1
+ """
2
+ Key handling utilities for DSA keys, domain parameters and signatures..
3
+ """
4
+
5
+ from asn1crypto.algos import DSASignature
6
+ from asn1crypto.core import Integer
7
+ from asn1crypto.keys import DSAParams
8
+
9
+ from pkcs11.constants import Attribute
10
+ from pkcs11.util import biginteger
11
+
12
+
13
+ def decode_dsa_domain_parameters(der):
14
+ """
15
+ Decode RFC 3279 DER-encoded Dss-Params.
16
+
17
+ :param bytes der: DER-encoded parameters
18
+ :rtype: dict(Attribute,*)
19
+ """
20
+
21
+ params = DSAParams.load(der)
22
+
23
+ return {
24
+ Attribute.BASE: biginteger(params["g"]),
25
+ Attribute.PRIME: biginteger(params["p"]),
26
+ Attribute.SUBPRIME: biginteger(params["q"]),
27
+ }
28
+
29
+
30
+ def encode_dsa_domain_parameters(obj):
31
+ """
32
+ Encode RFC 3279 DER-encoded Dss-Params.
33
+
34
+ :param DomainParameters obj: domain parameters
35
+ :rtype: bytes
36
+ """
37
+ asn1 = DSAParams(
38
+ {
39
+ "g": int.from_bytes(obj[Attribute.BASE], byteorder="big"),
40
+ "p": int.from_bytes(obj[Attribute.PRIME], byteorder="big"),
41
+ "q": int.from_bytes(obj[Attribute.SUBPRIME], byteorder="big"),
42
+ }
43
+ )
44
+
45
+ return asn1.dump()
46
+
47
+
48
+ def encode_dsa_public_key(key):
49
+ """
50
+ Encode DSA public key into RFC 3279 DER-encoded format.
51
+
52
+ :param PublicKey key: public key
53
+ :rtype: bytes
54
+ """
55
+
56
+ asn1 = Integer(int.from_bytes(key[Attribute.VALUE], byteorder="big"))
57
+
58
+ return asn1.dump()
59
+
60
+
61
+ def decode_dsa_public_key(der):
62
+ """
63
+ Decode a DSA public key from RFC 3279 DER-encoded format.
64
+
65
+ Returns a `biginteger` encoded as bytes.
66
+
67
+ :param bytes der: DER-encoded public key
68
+ :rtype: bytes
69
+ """
70
+
71
+ asn1 = Integer.load(der)
72
+
73
+ return biginteger(asn1)
74
+
75
+
76
+ def encode_dsa_signature(signature):
77
+ """
78
+ Encode a signature (generated by :meth:`pkcs11.SignMixin.sign`) into
79
+ DER-encoded ASN.1 (Dss_Sig_Value) format.
80
+
81
+ :param bytes signature: signature as bytes
82
+ :rtype: bytes
83
+ """
84
+
85
+ asn1 = DSASignature.from_p1363(signature)
86
+
87
+ return asn1.dump()
88
+
89
+
90
+ def decode_dsa_signature(der):
91
+ """
92
+ Decode a DER-encoded ASN.1 (Dss_Sig_Value) signature (as generated by
93
+ OpenSSL/X.509) into PKCS #11 format.
94
+
95
+ :param bytes der: DER-encoded signature
96
+ :rtype bytes:
97
+ """
98
+
99
+ asn1 = DSASignature.load(der)
100
+
101
+ return asn1.to_p1363()
pkcs11/util/ec.py ADDED
@@ -0,0 +1,133 @@
1
+ """
2
+ Key handling utilities for EC keys (ANSI X.62/RFC3279), domain parameter and
3
+ signatures.
4
+ """
5
+
6
+ from asn1crypto.algos import DSASignature
7
+ from asn1crypto.core import OctetString
8
+ from asn1crypto.keys import (
9
+ ECDomainParameters,
10
+ ECPrivateKey,
11
+ NamedCurve,
12
+ PublicKeyInfo,
13
+ )
14
+
15
+ from pkcs11.constants import Attribute, ObjectClass
16
+ from pkcs11.mechanisms import KeyType
17
+
18
+
19
+ def encode_named_curve_parameters(oid):
20
+ """
21
+ Return DER-encoded ANSI X.62 EC parameters for a named curve.
22
+
23
+ Curve names are given by object identifier or common name. Names come
24
+ from `asn1crypto
25
+ <https://github.com/wbond/asn1crypto/blob/master/asn1crypto/keys.py#L338>`_.
26
+
27
+ :param str oid: OID or named curve
28
+ :rtype: bytes
29
+ """
30
+ return ECDomainParameters(
31
+ name="named",
32
+ value=NamedCurve.unmap(oid),
33
+ ).dump()
34
+
35
+
36
+ def decode_ec_public_key(der, encode_ec_point=True):
37
+ """
38
+ Decode a DER-encoded EC public key as stored by OpenSSL into a dictionary
39
+ of attributes able to be passed to :meth:`pkcs11.Session.create_object`.
40
+
41
+ .. note:: **encode_ec_point**
42
+
43
+ For use as an attribute `EC_POINT` should be DER-encoded (True).
44
+
45
+ For key derivation implementations can vary. Since v2.30 the
46
+ specification says implementations MUST accept a raw `EC_POINT` for
47
+ ECDH (False), however not all implementations follow this yet.
48
+
49
+ :param bytes der: DER-encoded key
50
+ :param encode_ec_point: See text.
51
+ :rtype: dict(Attribute,*)
52
+ """
53
+ asn1 = PublicKeyInfo.load(der)
54
+
55
+ assert asn1.algorithm == "ec", "Wrong algorithm, not an EC key!"
56
+
57
+ ecpoint = bytes(asn1["public_key"])
58
+
59
+ if encode_ec_point:
60
+ ecpoint = OctetString(ecpoint).dump()
61
+
62
+ return {
63
+ Attribute.KEY_TYPE: KeyType.EC,
64
+ Attribute.CLASS: ObjectClass.PUBLIC_KEY,
65
+ Attribute.EC_PARAMS: asn1["algorithm"]["parameters"].dump(),
66
+ Attribute.EC_POINT: ecpoint,
67
+ }
68
+
69
+
70
+ def decode_ec_private_key(der):
71
+ """
72
+ Decode a DER-encoded EC private key as stored by OpenSSL into a dictionary
73
+ of attributes able to be passed to :meth:`pkcs11.Session.create_object`.
74
+
75
+ :param bytes der: DER-encoded key
76
+ :rtype: dict(Attribute,*)
77
+ """
78
+
79
+ asn1 = ECPrivateKey.load(der)
80
+
81
+ return {
82
+ Attribute.KEY_TYPE: KeyType.EC,
83
+ Attribute.CLASS: ObjectClass.PRIVATE_KEY,
84
+ Attribute.EC_PARAMS: asn1["parameters"].chosen.dump(),
85
+ Attribute.VALUE: asn1["private_key"].contents,
86
+ }
87
+
88
+
89
+ def encode_ec_public_key(key):
90
+ """
91
+ Encode a DER-encoded EC public key as stored by OpenSSL.
92
+
93
+ :param PublicKey key: EC public key
94
+ :rtype: bytes
95
+ """
96
+
97
+ ecparams = ECDomainParameters.load(key[Attribute.EC_PARAMS])
98
+ ecpoint = bytes(OctetString.load(key[Attribute.EC_POINT]))
99
+
100
+ return PublicKeyInfo(
101
+ {
102
+ "algorithm": {
103
+ "algorithm": "ec",
104
+ "parameters": ecparams,
105
+ },
106
+ "public_key": ecpoint,
107
+ }
108
+ ).dump()
109
+
110
+
111
+ def encode_ecdsa_signature(signature):
112
+ """
113
+ Encode a signature (generated by :meth:`pkcs11.SignMixin.sign`) into
114
+ DER-encoded ASN.1 (ECDSA_Sig_Value) format.
115
+
116
+ :param bytes signature: signature as bytes
117
+ :rtype: bytes
118
+ """
119
+
120
+ return DSASignature.from_p1363(signature).dump()
121
+
122
+
123
+ def decode_ecdsa_signature(der):
124
+ """
125
+ Decode a DER-encoded ASN.1 (ECDSA_Sig_Value) signature (as generated by
126
+ OpenSSL/X.509) into PKCS #11 format.
127
+
128
+ :param bytes der: DER-encoded signature
129
+ :rtype bytes:
130
+ """
131
+
132
+ asn1 = DSASignature.load(der)
133
+ return asn1.to_p1363()
pkcs11/util/rsa.py ADDED
@@ -0,0 +1,81 @@
1
+ """
2
+ Key handling utilities for RSA keys (PKCS#1).
3
+ """
4
+
5
+ from asn1crypto.keys import RSAPrivateKey, RSAPublicKey
6
+
7
+ from pkcs11.constants import Attribute, MechanismFlag, ObjectClass
8
+ from pkcs11.defaults import DEFAULT_KEY_CAPABILITIES
9
+ from pkcs11.mechanisms import KeyType
10
+ from pkcs11.util import biginteger
11
+
12
+
13
+ def decode_rsa_private_key(der, capabilities=None):
14
+ """
15
+ Decode a RFC2437 (PKCS#1) DER-encoded RSA private key into a dictionary of
16
+ attributes able to be passed to :meth:`pkcs11.Session.create_object`.
17
+
18
+ :param bytes der: DER-encoded key
19
+ :param MechanismFlag capabilities: Optional key capabilities
20
+ :rtype: dict(Attribute,*)
21
+ """
22
+ if capabilities is None:
23
+ capabilities = DEFAULT_KEY_CAPABILITIES[KeyType.RSA]
24
+
25
+ key = RSAPrivateKey.load(der)
26
+
27
+ return {
28
+ Attribute.CLASS: ObjectClass.PRIVATE_KEY,
29
+ Attribute.KEY_TYPE: KeyType.RSA,
30
+ Attribute.MODULUS: biginteger(key["modulus"]),
31
+ Attribute.PUBLIC_EXPONENT: biginteger(key["public_exponent"]),
32
+ Attribute.PRIVATE_EXPONENT: biginteger(key["private_exponent"]),
33
+ Attribute.PRIME_1: biginteger(key["prime1"]),
34
+ Attribute.PRIME_2: biginteger(key["prime2"]),
35
+ Attribute.EXPONENT_1: biginteger(key["exponent1"]),
36
+ Attribute.EXPONENT_2: biginteger(key["exponent2"]),
37
+ Attribute.COEFFICIENT: biginteger(key["coefficient"]),
38
+ Attribute.DECRYPT: MechanismFlag.DECRYPT in capabilities,
39
+ Attribute.SIGN: MechanismFlag.SIGN in capabilities,
40
+ Attribute.UNWRAP: MechanismFlag.UNWRAP in capabilities,
41
+ }
42
+
43
+
44
+ def decode_rsa_public_key(der, capabilities=None):
45
+ """
46
+ Decode a RFC2437 (PKCS#1) DER-encoded RSA public key into a dictionary of
47
+ attributes able to be passed to :meth:`pkcs11.Session.create_object`.
48
+
49
+ :param bytes der: DER-encoded key
50
+ :param MechanismFlag capabilities: Optional key capabilities
51
+ :rtype: dict(Attribute,*)
52
+ """
53
+
54
+ if capabilities is None:
55
+ capabilities = DEFAULT_KEY_CAPABILITIES[KeyType.RSA]
56
+
57
+ key = RSAPublicKey.load(der)
58
+ return {
59
+ Attribute.CLASS: ObjectClass.PUBLIC_KEY,
60
+ Attribute.KEY_TYPE: KeyType.RSA,
61
+ Attribute.MODULUS: biginteger(key["modulus"]),
62
+ Attribute.PUBLIC_EXPONENT: biginteger(key["public_exponent"]),
63
+ Attribute.ENCRYPT: MechanismFlag.ENCRYPT in capabilities,
64
+ Attribute.VERIFY: MechanismFlag.VERIFY in capabilities,
65
+ Attribute.WRAP: MechanismFlag.WRAP in capabilities,
66
+ }
67
+
68
+
69
+ def encode_rsa_public_key(key):
70
+ """
71
+ Encode an RSA public key into PKCS#1 DER-encoded format.
72
+
73
+ :param PublicKey key: RSA public key
74
+ :rtype: bytes
75
+ """
76
+ return RSAPublicKey(
77
+ {
78
+ "modulus": int.from_bytes(key[Attribute.MODULUS], byteorder="big"),
79
+ "public_exponent": int.from_bytes(key[Attribute.PUBLIC_EXPONENT], byteorder="big"),
80
+ }
81
+ ).dump()
pkcs11/util/x509.py ADDED
@@ -0,0 +1,129 @@
1
+ """
2
+ Certificate handling utilities for X.509 (SSL) certificates.
3
+ """
4
+
5
+ from asn1crypto.core import OctetString
6
+ from asn1crypto.x509 import Certificate
7
+
8
+ from pkcs11.constants import Attribute, CertificateType, ObjectClass
9
+ from pkcs11.mechanisms import KeyType
10
+
11
+
12
+ def decode_x509_public_key(der):
13
+ """
14
+ Decode a DER-encoded X.509 certificate's public key into a set of
15
+ attributes able to be passed to :meth:`pkcs11.Session.create_object`.
16
+
17
+ For PEM-encoded certificates, use :func:`asn1crypto.pem.unarmor`.
18
+
19
+ .. warning::
20
+
21
+ Does not verify certificate.
22
+
23
+ :param bytes der: DER-encoded certificate
24
+ :rtype: dict(Attribute,*)
25
+ """
26
+ x509 = Certificate.load(der)
27
+ key_info = x509.public_key
28
+ key = bytes(key_info["public_key"])
29
+
30
+ key_type = {
31
+ "rsa": KeyType.RSA,
32
+ "dsa": KeyType.DSA,
33
+ "ec": KeyType.EC,
34
+ }[key_info.algorithm]
35
+
36
+ attrs = {
37
+ Attribute.CLASS: ObjectClass.PUBLIC_KEY,
38
+ Attribute.KEY_TYPE: key_type,
39
+ }
40
+
41
+ if key_type is KeyType.RSA:
42
+ from .rsa import decode_rsa_public_key
43
+
44
+ attrs.update(decode_rsa_public_key(key))
45
+ elif key_type is KeyType.DSA:
46
+ from .dsa import decode_dsa_domain_parameters, decode_dsa_public_key
47
+
48
+ params = key_info["algorithm"]["parameters"].dump()
49
+
50
+ attrs.update(decode_dsa_domain_parameters(params))
51
+ attrs.update(
52
+ {
53
+ Attribute.VALUE: decode_dsa_public_key(key),
54
+ }
55
+ )
56
+ elif key_type is KeyType.EC:
57
+ params = key_info["algorithm"]["parameters"].dump()
58
+
59
+ # bytes(key_info['public_key']) returns the binary encoding
60
+ # of the EC point itself (decoded from its BitString representation in X.509),
61
+ # but PKCS#11 expects this as a DER OctetString.
62
+ key = OctetString(key).dump()
63
+ attrs.update(
64
+ {
65
+ Attribute.EC_PARAMS: params,
66
+ Attribute.EC_POINT: key,
67
+ }
68
+ )
69
+ else:
70
+ raise AssertionError("Should not be reached")
71
+
72
+ return attrs
73
+
74
+
75
+ def decode_x509_certificate(der, extended_set=False):
76
+ """
77
+ Decode a DER-encoded X.509 certificate into a dictionary of
78
+ attributes able to be passed to :meth:`pkcs11.Session.create_object`.
79
+
80
+ Optionally pass `extended_set` to include additional attributes:
81
+ start date, end date and key identifiers.
82
+
83
+ For PEM-encoded certificates, use :func:`asn1crypto.pem.unarmor`.
84
+
85
+ .. warning::
86
+
87
+ Does not verify certificate.
88
+
89
+ :param bytes der: DER-encoded certificate
90
+ :param extended_set: decodes more metadata about the certificate
91
+ :rtype: dict(Attribute,*)
92
+ """
93
+ x509 = Certificate.load(der)
94
+ subject = x509.subject
95
+ issuer = x509.issuer
96
+ serial = x509["tbs_certificate"]["serial_number"]
97
+
98
+ template = {
99
+ Attribute.CLASS: ObjectClass.CERTIFICATE,
100
+ Attribute.CERTIFICATE_TYPE: CertificateType.X_509,
101
+ Attribute.SUBJECT: subject.dump(),
102
+ Attribute.ISSUER: issuer.dump(),
103
+ Attribute.SERIAL_NUMBER: serial.dump(),
104
+ Attribute.VALUE: x509.dump(),
105
+ }
106
+
107
+ if extended_set:
108
+ start_date = x509["tbs_certificate"]["validity"]["not_before"].native.date()
109
+ end_date = x509["tbs_certificate"]["validity"]["not_after"].native.date()
110
+
111
+ template.update(
112
+ {
113
+ Attribute.START_DATE: start_date,
114
+ Attribute.END_DATE: end_date,
115
+ }
116
+ )
117
+
118
+ # FIXME: is this correct?
119
+ try:
120
+ template[Attribute.HASH_OF_SUBJECT_PUBLIC_KEY] = x509.key_identifier
121
+ except KeyError:
122
+ pass
123
+
124
+ try:
125
+ template[Attribute.HASH_OF_ISSUER_PUBLIC_KEY] = x509.authority_key_identifier
126
+ except KeyError:
127
+ pass
128
+
129
+ return template