-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attempt side-channel free RSA decryption #438
Changes from all commits
0aca085
bcd83cf
b912756
0cfb77d
44d6fd4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
from .rsakey import * | ||
from .python_rsakey import Python_RSAKey | ||
from .compat import compatAscii2Bytes | ||
import sys | ||
|
||
#copied from M2Crypto.util.py, so when we load the local copy of m2 | ||
#we can still use it | ||
|
@@ -67,13 +68,21 @@ def _rawPrivateKeyOp(self, message): | |
ciphertext = bytesToNumber(bytearray(string)) | ||
return ciphertext | ||
|
||
def _raw_private_key_op_bytes(self, message): | ||
return bytearray(m2.rsa_private_encrypt(self.rsa, bytes(message), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
m2.no_padding)) | ||
|
||
def _rawPublicKeyOp(self, ciphertext): | ||
data = numberToByteArray(ciphertext, numBytes(self.n)) | ||
string = m2.rsa_public_decrypt(self.rsa, bytes(data), | ||
m2.no_padding) | ||
message = bytesToNumber(bytearray(string)) | ||
return message | ||
|
||
def _raw_public_key_op_bytes(self, ciphertext): | ||
return bytearray(m2.rsa_public_decrypt(self.rsa, bytes(ciphertext), | ||
m2.no_padding)) | ||
|
||
def acceptsPassword(self): return True | ||
|
||
def write(self, password=None): | ||
|
@@ -151,6 +160,13 @@ def f():pass | |
key._hasPrivateKey = False | ||
else: | ||
raise SyntaxError() | ||
if key._hasPrivateKey: | ||
if sys.version_info < (3, 0): | ||
b64_key = str(key.write()) | ||
else: | ||
b64_key = str(key.write(), "ascii") | ||
py_key = Python_RSAKey.parsePEM(b64_key) | ||
key.d = py_key.d | ||
return key | ||
finally: | ||
m2.bio_free(bio) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,9 +33,39 @@ def parsePEM(s, passwordCallback=None): | |
elif pemSniff(s, "EC PRIVATE KEY"): | ||
bytes = dePem(s, "EC PRIVATE KEY") | ||
return Python_Key._parse_ecc_ssleay(bytes) | ||
elif pemSniff(s, "PUBLIC KEY"): | ||
bytes = dePem(s, "PUBLIC KEY") | ||
return Python_Key._parse_public_key(bytes) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid too many |
||
else: | ||
raise SyntaxError("Not a PEM private key file") | ||
|
||
@staticmethod | ||
def _parse_public_key(bytes): | ||
# public keys are encoded as the subject_public_key_info objects | ||
spk_info = ASN1Parser(bytes) | ||
|
||
# first element of the SEQUENCE is the AlgorithmIdentifier | ||
alg_id = spk_info.getChild(0) | ||
|
||
# AlgId has two elements, the OID of the algorithm and parameters | ||
# parameters generally have to be NULL, with exception of RSA-PSS | ||
|
||
alg_oid = alg_id.getChild(0) | ||
|
||
if list(alg_oid.value) != [42, 134, 72, 134, 247, 13, 1, 1, 1]: | ||
raise SyntaxError("Only RSA Public keys supported") | ||
|
||
subject_public_key = ASN1Parser( | ||
ASN1Parser(spk_info.getChildBytes(1)).value[1:]) | ||
|
||
modulus = subject_public_key.getChild(0) | ||
exponent = subject_public_key.getChild(1) | ||
|
||
n = bytesToNumber(modulus.value) | ||
e = bytesToNumber(exponent.value) | ||
|
||
return Python_RSAKey(n, e, key_type="rsa") | ||
|
||
@staticmethod | ||
def _parse_pkcs8(bytes): | ||
parser = ASN1Parser(bytes) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the syntax. Why is
type(key)
at the end of the line?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert will print the second element in the tuple on error, it's so that if the assert fails, it will print result of
type(key)