File: verify_rsa.py

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (69 lines) | stat: -rw-r--r-- 2,444 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from ct.crypto import error
from ct.crypto import pem
from ct.proto import client_pb2

import Crypto.Hash.SHA256
import Crypto.PublicKey.RSA
import Crypto.Signature.PKCS1_v1_5

class RsaVerifier(object):
    """Verifies RSA signatures."""

    # The signature algorithm used for this public key.
    SIGNATURE_ALGORITHM = client_pb2.DigitallySigned.RSA
    # The hash algorithm used for this public key.
    HASH_ALGORITHM = client_pb2.DigitallySigned.SHA256

    # Markers to look for when reading a PEM-encoded RSA public key.
    __READ_MARKERS = ("PUBLIC KEY", "RSA PUBLIC KEY")
    # A marker to write when writing a PEM-encoded RSA public key.
    __WRITE_MARKER = "RSA PUBLIC KEY"

    def __init__(self, key_info):
        """Creates a verifier that uses a PEM-encoded RSA public key.

        Args:
        - key_info: KeyInfo protobuf message

        Raises:
        - PemError: If the key has an invalid encoding
        """
        if (key_info.type != client_pb2.KeyInfo.RSA):
            raise error.UnsupportedAlgorithmError(
                "Expected RSA key, but got key type %d" % key_info.type)

        # Will raise a PemError on invalid encoding
        self.__der, _ = pem.from_pem(key_info.pem_key, self.__READ_MARKERS)
        try:
            self.__key = Crypto.PublicKey.RSA.importKey(self.__der)
        except (ValueError, IndexError, TypeError) as e:
            raise error.EncodingError(e)

    def __repr__(self):
        return "%s(public key: %r)" % (self.__class__.__name__,
                                       pem.to_pem(self.__der,
                                                  self.__WRITE_MARKER))

    @error.returns_true_or_raises
    def verify(self, signature_input, signature):
        """Verifies the signature was created by the owner of the public key.

        Args:
        - signature_input: The data that was originally signed.
        - signature: An RSA SHA256 signature.

        Returns:
        - True if the signature verifies.

        Raises:
        - error.SignatureError: If the signature fails verification.
        """
        verifier = Crypto.Signature.PKCS1_v1_5.new(self.__key)
        sha256_hash = Crypto.Hash.SHA256.new(signature_input)

        if verifier.verify(sha256_hash, signature):
            return True
        else:
            raise error.SignatureError("Signature did not verify: %s",
                                       signature.encode("hex"))