Skip to content

Commit

Permalink
Use cryptography instead of OpenSSL
Browse files Browse the repository at this point in the history
  • Loading branch information
moses-palmer committed Aug 24, 2015
1 parent 2c1babb commit 700ea09
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 33 deletions.
58 changes: 31 additions & 27 deletions lib/truepy/_license.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@
import gzip
import hashlib
import io
import OpenSSL
import sys

import cryptography.x509

from Crypto.Cipher import DES

from cryptography.hazmat import backends
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dsa, padding, rsa

from . import LicenseData, fromstring
from ._bean import deserialize, serialize, to_document
from ._bean_serializers import bean_class
from ._name import Name


@bean_class('de.schlichtherle.xml.GenericCertificate')
Expand Down Expand Up @@ -142,52 +148,51 @@ def issue(self, certificate, key, digest='SHA1', **license_data):
else:
if 'issuer' in license_data:
raise ValueError('issuer must not be passed')
license_data['issuer'] = ','.join('='.join(
str(part, 'ascii') if sys.version_info.major > 2
else part for part in parts)
for parts in certificate.get_subject().get_components())
issuer = Name.from_x509_name(certificate.subject)
license_data['issuer'] = str(issuer)
try:
license_data = LicenseData(**license_data)
except TypeError:
raise ValueError('invalid keyword arguments')
if not isinstance(license_data, LicenseData):
raise ValueError('invalid license_data: %s', license_data)

encoded = to_document(serialize(license_data))

if key.type() == OpenSSL.crypto.TYPE_RSA:
if isinstance(key, rsa.RSAPrivateKey):
encryption = 'RSA'
elif key.type() == OpenSSL.crypto.TYPE_DSA:
elif isinstance(key, dsa.DSAPrivateKey):
encryption = 'DSA'
else:
raise ValueError('unknown key type')

signature = base64.b64encode(OpenSSL.crypto.sign(
key,
encoded.encode('ascii'),
digest)).decode('ascii')
encoded = to_document(serialize(license_data))

signature_algorithm = 'with'.join((digest, encryption))
signer = key.signer(
padding.PKCS1v15(),
getattr(hashes, digest)())
signer.update(encoded.encode('ascii'))
signature = base64.b64encode(signer.finalize()).decode('ascii')

return License(encoded, signature, signature_algorithm)
return License(encoded, signature, 'with'.join((digest, encryption)))

def verify(self, certificate):
"""Verifies the signature of this certificate against a certificate.
:param OpenSSL.crypto.X509 certificate: The issuer certificate.
:param certificate: The issuer certificate.
:type certificate: bytes or cryptography.x509.Certificate
:raises truepy.License.InvalidSignatureException: if the signature does
not match
"""
certificate = self._certificate(certificate)

verifier = certificate.public_key().verifier(
base64.b64decode(self.signature),
padding.PKCS1v15(),
getattr(hashes, self._signature_digest)())
verifier.update(self.encoded.encode('ascii'))
try:
OpenSSL.crypto.verify(
certificate,
base64.b64decode(self.signature),
self.encoded.encode('ascii'),
self._signature_digest)
except Exception as e:
verifier.verify()
except cryptography.exceptions.InvalidSignature as e:
raise self.InvalidSignatureException(e)

@classmethod
Expand All @@ -201,13 +206,12 @@ def _certificate(self, certificate):
:return: a parsed certificate
"""
if isinstance(certificate, OpenSSL.crypto.X509):
if isinstance(certificate, cryptography.x509.Certificate):
return certificate
else:
return OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM,
certificate)

return cryptography.x509.load_pem_x509_certificate(
certificate,
backends.default_backend())

@classmethod
def _key_iv(self, password, salt=_SALT, iterations=_ITERATIONS,
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@

REQUIREMENTS = [
'cryptography >=1.0',
'pycrypto >=2.6.1',
'pyOpenSSL >=0.14']
'pycrypto >=2.6.1']


def setup(**kwargs):
Expand Down
11 changes: 7 additions & 4 deletions tests/license_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

import base64
import io
import OpenSSL

from cryptography.hazmat import backends
from cryptography.hazmat.primitives import serialization

from truepy import LicenseData, License
from truepy._bean import serialize, to_document
Expand Down Expand Up @@ -271,9 +273,10 @@ def key(self):
-----END ENCRYPTED PRIVATE KEY-----'''.splitlines()
if line.strip())
PASSWORD = b'SecretPassword'
return OpenSSL.crypto.load_privatekey(
OpenSSL.crypto.FILETYPE_PEM,
KEY, PASSWORD)
return serialization.load_pem_private_key(
KEY,
password=PASSWORD,
backend=backends.default_backend())

@property
def license(self):
Expand Down

0 comments on commit 700ea09

Please sign in to comment.