def create_sig(msg, key_file, nonce=None, nonce_len=CONFIG.NONCE_SIZE):
    """Create signature with nonce prepended to the message.

    TODO: Change this over to M2Crypto... PKey
          Protect against crypto unicode errors... is this sufficient?
          Do I need to escape?

    :param msg: Message to be signed
    :type msg: Anything with __str__ method

    :param key_file: Path to a file containing RSA key. Accepted formats
                     are the same as for `Crypto.PublicKey.RSA.importKey`.
    :type key_file: str

    :param nonce: Nonce to be used. If None, nonce of `nonce_len` size
                  will be randomly genereted.
    :type nonce: str or None

    :param nonce_len: Size of the automaticaly generated nonce.
    :type nonce_len: int

    :returns: Signature.
    :rtype: dict

    """
    msg = str(msg)
    key = Crypto.PublicKey.RSA.importKey(open(key_file).read())
    nonce = Random.get_random_bytes(nonce_len) if nonce is None else nonce

    msg_with_nonce = nonce + msg
    hashed = Crypto.Hash.SHA256.new(msg_with_nonce)
    signature = Crypto.Signature.PKCS1_v1_5.new(key).sign(hashed)

    logger.debug('%s signed as %s' % (msg_with_nonce, signature))

    n_bytes = binascii.unhexlify(leading_zeros(hex(key.n)[2:].rstrip("L")))
    e_bytes = binascii.unhexlify(leading_zeros(hex(key.e)[2:].rstrip("L")))

    return {
        "nonce": le_util.jose_b64encode(nonce),
        "alg": "RS256",
        "jwk": {
            "kty": "RSA",
            "n": le_util.jose_b64encode(n_bytes),
            "e": le_util.jose_b64encode(e_bytes),
        },
        "sig": le_util.jose_b64encode(signature),
    }
Example #2
0
def create_sig(msg, key_file, nonce=None, nonce_len=CONFIG.NONCE_SIZE):
    """Create signature with nonce prepended to the message.

    TODO: Change this over to M2Crypto... PKey
          Protect against crypto unicode errors... is this sufficient?
          Do I need to escape?

    :param msg: Message to be signed
    :type msg: Anything with __str__ method

    :param key_file: Path to a file containing RSA key. Accepted formats
                     are the same as for `Crypto.PublicKey.RSA.importKey`.
    :type key_file: str

    :param nonce: Nonce to be used. If None, nonce of `nonce_len` size
                  will be randomly genereted.
    :type nonce: str or None

    :param nonce_len: Size of the automaticaly generated nonce.
    :type nonce_len: int

    :returns: Signature.
    :rtype: dict

    """
    msg = str(msg)
    key = Crypto.PublicKey.RSA.importKey(open(key_file).read())
    nonce = Random.get_random_bytes(nonce_len) if nonce is None else nonce

    msg_with_nonce = nonce + msg
    hashed = Crypto.Hash.SHA256.new(msg_with_nonce)
    signature = Crypto.Signature.PKCS1_v1_5.new(key).sign(hashed)

    logger.debug('%s signed as %s' % (msg_with_nonce, signature))

    n_bytes = binascii.unhexlify(leading_zeros(hex(key.n)[2:].rstrip("L")))
    e_bytes = binascii.unhexlify(leading_zeros(hex(key.e)[2:].rstrip("L")))

    return {
        "nonce": le_util.jose_b64encode(nonce),
        "alg": "RS256",
        "jwk": {
            "kty": "RSA",
            "n": le_util.jose_b64encode(n_bytes),
            "e": le_util.jose_b64encode(e_bytes),
        },
        "sig": le_util.jose_b64encode(signature),
    }
def dvsni_gen_cert(filepath, name, r_b64, nonce, key):
    """Generate a DVSNI cert and save it to filepath.

    :param str filepath: destination to save certificate. This will overwrite
        any file that is currently at the location.
    :param str name: domain to validate
    :param str dvsni_r: jose base64 encoded dvsni r value
    :param str nonce: hex value of nonce

    :param key: Key to perform challenge
    :type key: :class:`letsencrypt.client.client.Client.Key`

    :returns: dvsni s value jose base64 encoded
    :rtype: str

    """
    # Generate S
    dvsni_s = Random.get_random_bytes(CONFIG.S_SIZE)
    dvsni_r = le_util.jose_b64decode(r_b64)

    # Generate extension
    ext = _dvsni_gen_ext(dvsni_r, dvsni_s)

    cert_pem = crypto_util.make_ss_cert(
        key.pem, [nonce + CONFIG.INVALID_EXT, name, ext])

    with open(filepath, 'w') as chall_cert_file:
            chall_cert_file.write(cert_pem)

    return le_util.jose_b64encode(dvsni_s)
    def test_standard(self):
        """Basic test for straightline code."""
        # This is a helper function that can be used for handling
        # open context managers more elegantly. It avoids dealing with
        # __enter__ and __exit__ calls.
        # http://www.voidspace.org.uk/python/mock/helpers.html#mock.mock_open
        m_open = mock.mock_open()
        with mock.patch("letsencrypt.client.challenge_util.open",
                        m_open, create=True):

            domain = "example.com"
            dvsni_r = "r_value"
            r_b64 = le_util.jose_b64encode(dvsni_r)
            pem = pkg_resources.resource_string(
                __name__, os.path.join("testdata", "rsa256_key.pem"))
            key = client.Client.Key("path", pem)
            nonce = "12345ABCDE"
            s_b64 = self._call("tmp.crt", domain, r_b64, nonce, key)

            self.assertTrue(m_open.called)
            self.assertEqual(m_open.call_args[0], ("tmp.crt", 'w'))
            self.assertEqual(m_open().write.call_count, 1)

            # pylint: disable=protected-access
            ext = challenge_util._dvsni_gen_ext(
                dvsni_r, le_util.jose_b64decode(s_b64))
            self._standard_check_cert(
                m_open().write.call_args[0][0], domain, nonce, ext)
Example #5
0
    def test_standard(self):
        """Basic test for straightline code."""
        # This is a helper function that can be used for handling
        # open context managers more elegantly. It avoids dealing with
        # __enter__ and __exit__ calls.
        # http://www.voidspace.org.uk/python/mock/helpers.html#mock.mock_open
        m_open = mock.mock_open()
        with mock.patch("letsencrypt.client.challenge_util.open",
                        m_open,
                        create=True):

            domain = "example.com"
            dvsni_r = "r_value"
            r_b64 = le_util.jose_b64encode(dvsni_r)
            pem = pkg_resources.resource_string(
                __name__, os.path.join("testdata", "rsa256_key.pem"))
            key = client.Client.Key("path", pem)
            nonce = "12345ABCDE"
            s_b64 = self._call("tmp.crt", domain, r_b64, nonce, key)

            self.assertTrue(m_open.called)
            self.assertEqual(m_open.call_args[0], ("tmp.crt", 'w'))
            self.assertEqual(m_open().write.call_count, 1)

            # pylint: disable=protected-access
            ext = challenge_util._dvsni_gen_ext(dvsni_r,
                                                le_util.jose_b64decode(s_b64))
            self._standard_check_cert(m_open().write.call_args[0][0], domain,
                                      nonce, ext)
def dvsni_gen_cert(filepath, name, r_b64, nonce, key):
    """Generate a DVSNI cert and save it to filepath.

    :param str filepath: destination to save certificate. This will overwrite
        any file that is currently at the location.
    :param str name: domain to validate
    :param str dvsni_r: jose base64 encoded dvsni r value
    :param str nonce: hex value of nonce

    :param key: Key to perform challenge
    :type key: :class:`letsencrypt.client.client.Client.Key`

    :returns: dvsni s value jose base64 encoded
    :rtype: str

    """
    # Generate S
    dvsni_s = Random.get_random_bytes(CONFIG.S_SIZE)
    dvsni_r = le_util.jose_b64decode(r_b64)

    # Generate extension
    ext = _dvsni_gen_ext(dvsni_r, dvsni_s)

    cert_pem = crypto_util.make_ss_cert(
        key.pem, [nonce + CONFIG.INVALID_EXT, name, ext])

    with open(filepath, 'w') as chall_cert_file:
        chall_cert_file.write(cert_pem)

    return le_util.jose_b64encode(dvsni_s)
Example #7
0
def certificate_request(csr_der, key):
    """Create ACME "certificateRequest" message.

    :param str csr_der: DER encoded CSR.
    :param key: TODO

    :returns: ACME "certificateRequest" message.
    :rtype: dict

    """
    return {
        "type": "certificateRequest",
        "csr": le_util.jose_b64encode(csr_der),
        "signature": crypto_util.create_sig(csr_der, key),
    }
Example #8
0
def revocation_request(cert_der, key, nonce=None):
    """Create ACME "revocationRequest" message.

    :param str cert_der: DER encoded certificate.
    :param str key: Key in string form. Accepted formats
        are the same as for `Crypto.PublicKey.RSA.importKey`.
    :param str nonce: Nonce used for signature. Useful for testing.

    :returns: ACME "revocationRequest" message.
    :rtype: dict

    """
    return {
        "type": "revocationRequest",
        "certificate": le_util.jose_b64encode(cert_der),
        "signature": crypto_util.create_sig(cert_der, key, nonce),
    }
Example #9
0
def revocation_request(cert_der, key, nonce=None):
    """Create ACME "revocationRequest" message.

    :param str cert_der: DER encoded certificate.
    :param str key: Key in string form. Accepted formats
        are the same as for `Crypto.PublicKey.RSA.importKey`.
    :param str nonce: Nonce used for signature. Useful for testing.

    :returns: ACME "revocationRequest" message.
    :rtype: dict

    """
    return {
        "type": "revocationRequest",
        "certificate": le_util.jose_b64encode(cert_der),
        "signature": crypto_util.create_sig(cert_der, key, nonce),
    }
Example #10
0
def revocation_request(key_file, cert_der):
    """Create ACME "revocationRequest" message.

    :param str key_file: Path to a file containing RSA key. Accepted
        formats are the same as for `Crypto.PublicKey.RSA.importKey`.

    :param str cert_der: DER encoded certificate.

    :returns: ACME "revocationRequest" message.
    :rtype: dict

    """
    return {
        "type": "revocationRequest",
        "certificate": le_util.jose_b64encode(cert_der),
        "signature": crypto_util.create_sig(cert_der, key_file),
    }
Example #11
0
def certificate_request(csr_der, key):
    """Create ACME "certificateRequest" message.

    :param csr_der: DER encoded CSR.
    :type csr_der: str

    :param key: TODO
    :type key: TODO

    :returns: ACME "certificateRequest" message.
    :rtype: dict

    """
    return {
        "type": "certificateRequest",
        "csr": le_util.jose_b64encode(csr_der),
        "signature": crypto_util.create_sig(csr_der, key),
    }
Example #12
0
def revocation_request(key_file, cert_der):
    """Create ACME "revocationRequest" message.

    :param key_file: Path to a file containing RSA key. Accepted formats
                     are the same as for `Crypto.PublicKey.RSA.importKey`.
    :type key_file: str

    :param cert_der: DER encoded certificate.
    :type cert_der: str

    :returns: ACME "revocationRequest" message.
    :rtype: dict

    """
    return {
        "type": "revocationRequest",
        "certificate": le_util.jose_b64encode(cert_der),
        "signature": crypto_util.create_sig(cert_der, key_file),
    }
 def _call(self, data):
     from letsencrypt.client.le_util import jose_b64encode
     return jose_b64encode(data)
Example #14
0
 def _call(self, data):
     from letsencrypt.client.le_util import jose_b64encode
     return jose_b64encode(data)