diff options
author | panky-codes <pankaj.sarathy1992@gmail.com> | 2021-03-20 22:45:29 +0100 |
---|---|---|
committer | panky-codes <pankaj.sarathy1992@gmail.com> | 2021-03-20 22:45:29 +0100 |
commit | 534565088033221d29e968acf7267145ff10203b (patch) | |
tree | c93ae7c7aa7995204f56b979ff6524feba83763d /tools/mcuboot/imgtool/keys/__init__.py | |
parent | 754ac233040af805ffa2e15b24539d5d02a876e5 (diff) | |
parent | a3ff2e46ca9e663af864a2bd04b9afa3efbddfb8 (diff) |
Merged upstream
Diffstat (limited to 'tools/mcuboot/imgtool/keys/__init__.py')
-rw-r--r-- | tools/mcuboot/imgtool/keys/__init__.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/tools/mcuboot/imgtool/keys/__init__.py b/tools/mcuboot/imgtool/keys/__init__.py new file mode 100644 index 00000000..f25e2aae --- /dev/null +++ b/tools/mcuboot/imgtool/keys/__init__.py @@ -0,0 +1,94 @@ +# Copyright 2017 Linaro Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Cryptographic key management for imgtool. +""" + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateKey, RSAPublicKey) +from cryptography.hazmat.primitives.asymmetric.ec import ( + EllipticCurvePrivateKey, EllipticCurvePublicKey) +from cryptography.hazmat.primitives.asymmetric.ed25519 import ( + Ed25519PrivateKey, Ed25519PublicKey) +from cryptography.hazmat.primitives.asymmetric.x25519 import ( + X25519PrivateKey, X25519PublicKey) + +from .rsa import RSA, RSAPublic, RSAUsageError, RSA_KEY_SIZES +from .ecdsa import ECDSA256P1, ECDSA256P1Public, ECDSAUsageError +from .ed25519 import Ed25519, Ed25519Public, Ed25519UsageError +from .x25519 import X25519, X25519Public, X25519UsageError + + +class PasswordRequired(Exception): + """Raised to indicate that the key is password protected, but a + password was not specified.""" + pass + + +def load(path, passwd=None): + """Try loading a key from the given path. Returns None if the password wasn't specified.""" + with open(path, 'rb') as f: + raw_pem = f.read() + try: + pk = serialization.load_pem_private_key( + raw_pem, + password=passwd, + backend=default_backend()) + # Unfortunately, the crypto library raises unhelpful exceptions, + # so we have to look at the text. + except TypeError as e: + msg = str(e) + if "private key is encrypted" in msg: + return None + raise e + except ValueError: + # This seems to happen if the key is a public key, let's try + # loading it as a public key. + pk = serialization.load_pem_public_key( + raw_pem, + backend=default_backend()) + + if isinstance(pk, RSAPrivateKey): + if pk.key_size not in RSA_KEY_SIZES: + raise Exception("Unsupported RSA key size: " + pk.key_size) + return RSA(pk) + elif isinstance(pk, RSAPublicKey): + if pk.key_size not in RSA_KEY_SIZES: + raise Exception("Unsupported RSA key size: " + pk.key_size) + return RSAPublic(pk) + elif isinstance(pk, EllipticCurvePrivateKey): + if pk.curve.name != 'secp256r1': + raise Exception("Unsupported EC curve: " + pk.curve.name) + if pk.key_size != 256: + raise Exception("Unsupported EC size: " + pk.key_size) + return ECDSA256P1(pk) + elif isinstance(pk, EllipticCurvePublicKey): + if pk.curve.name != 'secp256r1': + raise Exception("Unsupported EC curve: " + pk.curve.name) + if pk.key_size != 256: + raise Exception("Unsupported EC size: " + pk.key_size) + return ECDSA256P1Public(pk) + elif isinstance(pk, Ed25519PrivateKey): + return Ed25519(pk) + elif isinstance(pk, Ed25519PublicKey): + return Ed25519Public(pk) + elif isinstance(pk, X25519PrivateKey): + return X25519(pk) + elif isinstance(pk, X25519PublicKey): + return X25519Public(pk) + else: + raise Exception("Unknown key type: " + str(type(pk))) |