Skip to content

Commit

Permalink
Finish off port to asn1crypto
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielle Madeley committed Sep 4, 2017
1 parent 2cb3e65 commit 886ff57
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 135 deletions.
2 changes: 0 additions & 2 deletions dev-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ Cython
setuptools_scm

# Used for tests
pyasn1
pyasn1-modules
oscrypto
cryptography

Expand Down
2 changes: 0 additions & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ jinja2==2.9.6 # via sphinx
markupsafe==1.0 # via jinja2
mccabe==0.6.1 # via flake8
oscrypto==0.18.0
pyasn1-modules==0.0.9
pyasn1==0.2.3
pycodestyle==2.3.1 # via flake8
pycparser==2.18 # via cffi
pyflakes==1.5.0 # via flake8
Expand Down
38 changes: 15 additions & 23 deletions pkcs11/util/dh.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,47 @@
"""
Key handling utilities for Diffie-Hellman keys.
These utilities depend on :mod:`pyasn1` and :mod:`pyasn1_modules`.
"""

from pyasn1.codec.der import encoder, decoder
from pyasn1_modules.rfc3279 import DomainParameters, DHPublicKey
from asn1crypto.algos import DHParameters
from asn1crypto.core import Integer

from . import biginteger
from ..constants import Attribute
from ..exceptions import AttributeTypeInvalid


def decode_x9_42_dh_domain_parameters(der):
def decode_dh_domain_parameters(der):
"""
Decode RFC3279 (X9.42) DER-encoded Diffie-Hellman domain parameters.
Decode DER-encoded Diffie-Hellman domain parameters.
:param bytes der: DER-encoded parameters
:rtype: dict(Attribute,*)
"""

params, _ = decoder.decode(der, asn1Spec=DomainParameters())
params = DHParameters.load(der)

return {
Attribute.BASE: biginteger(params['g']),
Attribute.PRIME: biginteger(params['p']),
Attribute.SUBPRIME: biginteger(params['q']),
}


def encode_x9_42_dh_domain_parameters(obj):
def encode_dh_domain_parameters(obj):
"""
Encode DH domain parameters into RFC 3279 (X9.42) DER-encoded format.
Encode DH domain parameters into DER-encoded format.
Calculates the subprime if it isn't available.
:param DomainParameters obj: domain parameters
:rtype: bytes
"""

asn1 = DomainParameters()
asn1['g'] = int.from_bytes(obj[Attribute.BASE], byteorder='big')
asn1['p'] = int.from_bytes(obj[Attribute.PRIME], byteorder='big')

try:
asn1['q'] = int.from_bytes(obj[Attribute.SUBPRIME], byteorder='big')
except AttributeTypeInvalid:
# If we don't have the subprime, calculate it.
asn1['q'] = (asn1['p'] - 1) // 2
asn1 = DHParameters({
'g': int.from_bytes(obj[Attribute.BASE], byteorder='big'),
'p': int.from_bytes(obj[Attribute.PRIME], byteorder='big'),
})

return encoder.encode(asn1)
return asn1.dump()


def encode_dh_public_key(key):
Expand All @@ -60,9 +52,9 @@ def encode_dh_public_key(key):
:rtype: bytes
"""

asn1 = DHPublicKey(int.from_bytes(key[Attribute.VALUE], byteorder='big'))
asn1 = Integer(int.from_bytes(key[Attribute.VALUE], byteorder='big'))

return encoder.encode(asn1)
return asn1.dump()


def decode_dh_public_key(der):
Expand All @@ -75,5 +67,5 @@ def decode_dh_public_key(der):
:rtype: bytes
"""

asn1, _ = decoder.decode(der, asn1Spec=DHPublicKey())
asn1 = Integer.load(der)
return biginteger(asn1)
47 changes: 18 additions & 29 deletions pkcs11/util/dsa.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
"""
Key handling utilities for DSA keys, domain parameters and signatures..
These utilities depend on :mod:`pyasn1` and :mod:`pyasn1_modules`.
"""

from pyasn1.codec.der import encoder, decoder
from pyasn1_modules.rfc3279 import Dss_Parms, Dss_Sig_Value, DSAPublicKey
from asn1crypto.core import Integer
from asn1crypto.keys import DSAParams
from asn1crypto.algos import DSASignature

from . import biginteger
from ..constants import Attribute
Expand All @@ -19,7 +18,7 @@ def decode_dsa_domain_parameters(der):
:rtype: dict(Attribute,*)
"""

params, _ = decoder.decode(der, asn1Spec=Dss_Parms())
params = DSAParams.load(der)

return {
Attribute.BASE: biginteger(params['g']),
Expand All @@ -35,12 +34,13 @@ def encode_dsa_domain_parameters(obj):
:param DomainParameters obj: domain parameters
:rtype: bytes
"""
asn1 = Dss_Parms()
asn1['g'] = int.from_bytes(obj[Attribute.BASE], byteorder='big')
asn1['p'] = int.from_bytes(obj[Attribute.PRIME], byteorder='big')
asn1['q'] = int.from_bytes(obj[Attribute.SUBPRIME], byteorder='big')
asn1 = DSAParams({
'g': int.from_bytes(obj[Attribute.BASE], byteorder='big'),
'p': int.from_bytes(obj[Attribute.PRIME], byteorder='big'),
'q': int.from_bytes(obj[Attribute.SUBPRIME], byteorder='big'),
})

return encoder.encode(asn1)
return asn1.dump()


def encode_dsa_public_key(key):
Expand All @@ -51,9 +51,9 @@ def encode_dsa_public_key(key):
:rtype: bytes
"""

asn1 = DSAPublicKey(int.from_bytes(key[Attribute.VALUE], byteorder='big'))
asn1 = Integer(int.from_bytes(key[Attribute.VALUE], byteorder='big'))

return encoder.encode(asn1)
return asn1.dump()


def decode_dsa_public_key(der):
Expand All @@ -66,7 +66,8 @@ def decode_dsa_public_key(der):
:rtype: bytes
"""

asn1, _ = decoder.decode(der, asn1Spec=DSAPublicKey())
asn1 = Integer.load(der)

return biginteger(asn1)


Expand All @@ -79,14 +80,9 @@ def encode_dsa_signature(signature):
:rtype: bytes
"""

part = len(signature) // 2
r, s = signature[:part], signature[part:]
asn1 = DSASignature.from_p1363(signature)

asn1 = Dss_Sig_Value()
asn1['r'] = int.from_bytes(r, byteorder='big')
asn1['s'] = int.from_bytes(s, byteorder='big')

return encoder.encode(asn1)
return asn1.dump()


def decode_dsa_signature(der):
Expand All @@ -98,13 +94,6 @@ def decode_dsa_signature(der):
:rtype bytes:
"""

asn1, _ = decoder.decode(der, asn1Spec=Dss_Sig_Value())

r = int(asn1['r'])
s = int(asn1['s'])
asn1 = DSASignature.load(der)

# r and s are both 20 bytes
return b''.join((
r.to_bytes(20, byteorder='big'),
s.to_bytes(20, byteorder='big'),
))
return asn1.to_p1363()
21 changes: 11 additions & 10 deletions pkcs11/util/rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from asn1crypto.keys import RSAPrivateKey, RSAPublicKey

from . import biginteger
from ..constants import Attribute, ObjectClass, MechanismFlag
from ..mechanisms import KeyType
from ..defaults import DEFAULT_KEY_CAPABILITIES
Expand All @@ -26,14 +27,14 @@ def decode_rsa_private_key(der, capabilities=None):
return {
Attribute.CLASS: ObjectClass.PRIVATE_KEY,
Attribute.KEY_TYPE: KeyType.RSA,
Attribute.MODULUS: key['modulus'],
Attribute.PUBLIC_EXPONENT: key['public_exponent'],
Attribute.PRIVATE_EXPONENT: key['private_exponent'],
Attribute.PRIME_1: key['prime1'],
Attribute.PRIME_2: key['prime2'],
Attribute.EXPONENT_1: key['exponent1'],
Attribute.EXPONENT_2: key['exponent2'],
Attribute.COEFFICIENT: key['coefficient'],
Attribute.MODULUS: biginteger(key['modulus']),
Attribute.PUBLIC_EXPONENT: biginteger(key['public_exponent']),
Attribute.PRIVATE_EXPONENT: biginteger(key['private_exponent']),
Attribute.PRIME_1: biginteger(key['prime1']),
Attribute.PRIME_2: biginteger(key['prime2']),
Attribute.EXPONENT_1: biginteger(key['exponent1']),
Attribute.EXPONENT_2: biginteger(key['exponent2']),
Attribute.COEFFICIENT: biginteger(key['coefficient']),
Attribute.DECRYPT: MechanismFlag.DECRYPT in capabilities,
Attribute.SIGN: MechanismFlag.SIGN in capabilities,
Attribute.UNWRAP: MechanismFlag.UNWRAP in capabilities,
Expand All @@ -57,8 +58,8 @@ def decode_rsa_public_key(der, capabilities=None):
return {
Attribute.CLASS: ObjectClass.PUBLIC_KEY,
Attribute.KEY_TYPE: KeyType.RSA,
Attribute.MODULUS: key['modulus'],
Attribute.PUBLIC_EXPONENT: key['public_exponent'],
Attribute.MODULUS: biginteger(key['modulus']),
Attribute.PUBLIC_EXPONENT: biginteger(key['public_exponent']),
Attribute.ENCRYPT: MechanismFlag.ENCRYPT in capabilities,
Attribute.VERIFY: MechanismFlag.VERIFY in capabilities,
Attribute.WRAP: MechanismFlag.WRAP in capabilities,
Expand Down
2 changes: 0 additions & 2 deletions pkcs11/util/x509.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""
Certificate handling utilities for X.509 (SSL) certificates.
These utilities depend on :mod:`pyasn1` and :mod:`pyasn1_modules`.
"""

from datetime import datetime
Expand Down
11 changes: 5 additions & 6 deletions tests/test_dh.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

from pkcs11 import Attribute, KeyType, DomainParameters, Mechanism
from pkcs11.util.dh import (
decode_x9_42_dh_domain_parameters,
encode_x9_42_dh_domain_parameters,
decode_dh_domain_parameters,
encode_dh_domain_parameters,
encode_dh_public_key,
)

Expand Down Expand Up @@ -105,11 +105,10 @@ def test_load_params(self):
""")

params = self.session.create_domain_parameters(
KeyType.X9_42_DH,
decode_x9_42_dh_domain_parameters(PARAMS),
KeyType.DH,
decode_dh_domain_parameters(PARAMS),
local=True)
self.assertIsInstance(params, DomainParameters)
self.assertEqual(len(params[Attribute.SUBPRIME]) * 8, 224)
self.assertEqual(params[Attribute.PRIME][:4],
b'\xAD\x10\x7E\x1E')

Expand All @@ -119,7 +118,7 @@ def test_generate_params(self):
self.assertIsInstance(params, DomainParameters)
self.assertEqual(params[Attribute.PRIME_BITS], 512)
self.assertEqual(len(params[Attribute.PRIME]) * 8, 512)
encode_x9_42_dh_domain_parameters(params)
encode_dh_domain_parameters(params)

# Test encoding the public key
public, _ = params.generate_keypair()
Expand Down
8 changes: 2 additions & 6 deletions tests/test_public_key_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ def test_rsa(self):

@requires(Mechanism.ECDSA_SHA1)
def test_ecdsa(self):
from pyasn1_modules.rfc3279 import prime256v1

# A key we generated earlier
self.session.create_domain_parameters(KeyType.EC, {
Attribute.EC_PARAMS: encode_named_curve_parameters(prime256v1),
Attribute.EC_PARAMS: encode_named_curve_parameters('secp256r1'),
}, local=True)\
.generate_keypair()

Expand All @@ -61,11 +59,9 @@ def test_ecdsa(self):

@requires(Mechanism.ECDH1_DERIVE)
def test_ecdh(self):
from pyasn1_modules.rfc3279 import prime256v1

# A key we generated earlier
self.session.create_domain_parameters(KeyType.EC, {
Attribute.EC_PARAMS: encode_named_curve_parameters(prime256v1),
Attribute.EC_PARAMS: encode_named_curve_parameters('secp256r1'),
}, local=True)\
.generate_keypair()

Expand Down
Loading

0 comments on commit 886ff57

Please sign in to comment.