129 lines
4.4 KiB
Python
129 lines
4.4 KiB
Python
# 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 absolute_import, division, print_function
|
|
|
|
import binascii
|
|
import itertools
|
|
import os
|
|
|
|
from cryptography.hazmat.backends.openssl.backend import backend
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
|
|
|
from tests.utils import load_pkcs1_vectors, load_vectors_from_file
|
|
|
|
|
|
def build_vectors(mgf1alg, hashalg, filename):
|
|
vectors = load_vectors_from_file(filename, load_pkcs1_vectors)
|
|
|
|
output = []
|
|
for vector in vectors:
|
|
# RSA keys for this must be long enough to accommodate the length of
|
|
# the underlying hash function. This means we can't use the keys from
|
|
# the sha1 test vectors for sha512 tests because 1024-bit keys are too
|
|
# small. Instead we parse the vectors for the test cases, then
|
|
# generate our own 2048-bit keys for each.
|
|
private, _ = vector
|
|
skey = rsa.generate_private_key(65537, 2048, backend)
|
|
pn = skey.private_numbers()
|
|
examples = private["examples"]
|
|
output.append(b"# =============================================")
|
|
output.append(b"# Example")
|
|
output.append(b"# Public key")
|
|
output.append(b"# Modulus:")
|
|
output.append(format(pn.public_numbers.n, "x"))
|
|
output.append(b"# Exponent:")
|
|
output.append(format(pn.public_numbers.e, "x"))
|
|
output.append(b"# Private key")
|
|
output.append(b"# Modulus:")
|
|
output.append(format(pn.public_numbers.n, "x"))
|
|
output.append(b"# Public exponent:")
|
|
output.append(format(pn.public_numbers.e, "x"))
|
|
output.append(b"# Exponent:")
|
|
output.append(format(pn.d, "x"))
|
|
output.append(b"# Prime 1:")
|
|
output.append(format(pn.p, "x"))
|
|
output.append(b"# Prime 2:")
|
|
output.append(format(pn.q, "x"))
|
|
output.append(b"# Prime exponent 1:")
|
|
output.append(format(pn.dmp1, "x"))
|
|
output.append(b"# Prime exponent 2:")
|
|
output.append(format(pn.dmq1, "x"))
|
|
output.append(b"# Coefficient:")
|
|
output.append(format(pn.iqmp, "x"))
|
|
pkey = skey.public_key()
|
|
vectorkey = rsa.RSAPrivateNumbers(
|
|
p=private["p"],
|
|
q=private["q"],
|
|
d=private["private_exponent"],
|
|
dmp1=private["dmp1"],
|
|
dmq1=private["dmq1"],
|
|
iqmp=private["iqmp"],
|
|
public_numbers=rsa.RSAPublicNumbers(
|
|
e=private["public_exponent"],
|
|
n=private["modulus"]
|
|
)
|
|
).private_key(backend)
|
|
count = 1
|
|
|
|
for example in examples:
|
|
message = vectorkey.decrypt(
|
|
binascii.unhexlify(example["encryption"]),
|
|
padding.OAEP(
|
|
mgf=padding.MGF1(algorithm=hashes.SHA1()),
|
|
algorithm=hashes.SHA1(),
|
|
label=None
|
|
)
|
|
)
|
|
assert message == binascii.unhexlify(example["message"])
|
|
ct = pkey.encrypt(
|
|
message,
|
|
padding.OAEP(
|
|
mgf=padding.MGF1(algorithm=mgf1alg),
|
|
algorithm=hashalg,
|
|
label=None
|
|
)
|
|
)
|
|
output.append(
|
|
b"# OAEP Example {0} alg={1} mgf1={2}".format(
|
|
count, hashalg.name, mgf1alg.name
|
|
)
|
|
)
|
|
count += 1
|
|
output.append(b"# Message:")
|
|
output.append(example["message"])
|
|
output.append(b"# Encryption:")
|
|
output.append(binascii.hexlify(ct))
|
|
|
|
return b"\n".join(output)
|
|
|
|
|
|
def write_file(data, filename):
|
|
with open(filename, "w") as f:
|
|
f.write(data)
|
|
|
|
|
|
oaep_path = os.path.join(
|
|
"asymmetric", "RSA", "pkcs-1v2-1d2-vec", "oaep-vect.txt"
|
|
)
|
|
hashalgs = [
|
|
hashes.SHA1(),
|
|
hashes.SHA224(),
|
|
hashes.SHA256(),
|
|
hashes.SHA384(),
|
|
hashes.SHA512(),
|
|
]
|
|
for hashtuple in itertools.product(hashalgs, hashalgs):
|
|
if (
|
|
isinstance(hashtuple[0], hashes.SHA1) and
|
|
isinstance(hashtuple[1], hashes.SHA1)
|
|
):
|
|
continue
|
|
|
|
write_file(
|
|
build_vectors(hashtuple[0], hashtuple[1], oaep_path),
|
|
"oaep-{0}-{1}.txt".format(hashtuple[0].name, hashtuple[1].name)
|
|
)
|