Example #1
0
        def _recomputeDigest(self):
            """
            Digest the fields and set self._digest to the hex digest.
            """
            sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend())
            number = bytearray(4)
            # Debug: sync-state.proto defines seq and session as uint64, but
            #   the original ChronoChat-js only digests 32 bits.
            self._int32ToLittleEndian(self._sessionNo, number)
            sha256.update(Blob(number, False).toBytes())
            self._int32ToLittleEndian(self._sequenceNo, number)
            sha256.update(Blob(number, False).toBytes())
            sequenceDigest = sha256.finalize()

            sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend())
            # Use Blob to convert a string to UTF-8 if needed.
            sha256.update(Blob(self._dataPrefix, False).toBytes());
            nameDigest = sha256.finalize()

            sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend())
            sha256.update(nameDigest)
            sha256.update(sequenceDigest)
            nodeDigest = sha256.finalize()
            # Use Blob to convert a str (Python 2) or bytes (Python 3) to hex.
            self._digest = Blob(nodeDigest, False).toHex()
Example #2
0
    def _verify_signature_with_pubkey(self, signed_info_c14n, raw_signature, key_value, signature_alg):
        if "ecdsa-" in signature_alg:
            ec_key_value = self._find(key_value, "ECKeyValue", namespace="dsig11")
            named_curve = self._find(ec_key_value, "NamedCurve", namespace="dsig11")
            public_key = self._find(ec_key_value, "PublicKey", namespace="dsig11")
            key_data = b64decode(public_key.text)[1:]
            x = bytes_to_long(key_data[:len(key_data)//2])
            y = bytes_to_long(key_data[len(key_data)//2:])
            curve_class = self.known_ecdsa_curves[named_curve.get("URI")]
            key = ec.EllipticCurvePublicNumbers(x=x, y=y, curve=curve_class()).public_key(backend=default_backend())
            verifier = key.verifier(raw_signature, ec.ECDSA(self._get_signature_digest_method(signature_alg)))
        elif "dsa-" in signature_alg:
            dsa_key_value = self._find(key_value, "DSAKeyValue")
            p = self._get_long(dsa_key_value, "P")
            q = self._get_long(dsa_key_value, "Q")
            g = self._get_long(dsa_key_value, "G", require=False)
            y = self._get_long(dsa_key_value, "Y")
            pn = dsa.DSAPublicNumbers(y=y, parameter_numbers=dsa.DSAParameterNumbers(p=p, q=q, g=g))
            key = pn.public_key(backend=default_backend())
            der_seq = DERSequenceOfIntegers([bytes_to_long(raw_signature[:len(raw_signature)//2]),
                                             bytes_to_long(raw_signature[len(raw_signature)//2:])])
            sig_as_der_seq = der_encoder.encode(der_seq)
            verifier = key.verifier(sig_as_der_seq, self._get_signature_digest_method(signature_alg))
        elif "rsa-" in signature_alg:
            rsa_key_value = self._find(key_value, "RSAKeyValue")
            modulus = self._get_long(rsa_key_value, "Modulus")
            exponent = self._get_long(rsa_key_value, "Exponent")
            key = rsa.RSAPublicNumbers(e=exponent, n=modulus).public_key(backend=default_backend())
            verifier = key.verifier(raw_signature, padding=PKCS1v15(),
                                    algorithm=self._get_signature_digest_method(signature_alg))
        else:
            raise NotImplementedError()

        verifier.update(signed_info_c14n)
        verifier.verify()
Example #3
0
    def test_invalid_key(self):
        kdf = PBKDF2HMAC(hashes.SHA1(), 20, b"salt", 10, default_backend())
        key = kdf.derive(b"password")

        kdf = PBKDF2HMAC(hashes.SHA1(), 20, b"salt", 10, default_backend())
        with pytest.raises(InvalidKey):
            kdf.verify(b"password2", key)
Example #4
0
    def create_ca(self, cn=ISSUER_CN):
        """Create root CA.

        :returns: bytes -- Root CA in PEM format.
        """
        self.ca_key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend(),
        )

        self.ca_public_key = self.ca_key.public_key()

        subject = self.issuer = x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, six.text_type(cn)),
        ])

        builder = x509.CertificateBuilder()
        builder = builder.subject_name(subject)
        builder = builder.issuer_name(self.issuer)
        builder = builder.public_key(self.ca_public_key)
        builder = builder.serial_number(x509.random_serial_number())
        builder = builder.not_valid_before(self.now)
        builder = builder.not_valid_after(self.now + self.delta)

        builder = builder.add_extension(
            x509.KeyUsage(
                digital_signature=False,
                content_commitment=False,
                key_encipherment=False,
                data_encipherment=False,
                key_agreement=False,
                key_cert_sign=True,
                crl_sign=True,
                encipher_only=False,
                decipher_only=False,
            ),
            critical=True,
        )

        builder = builder.add_extension(
            x509.BasicConstraints(ca=True, path_length=None),
            critical=True,
        )

        builder = builder.add_extension(
            x509.SubjectKeyIdentifier.from_public_key(self.ca_public_key),
            critical=False,
        )

        builder = builder.add_extension(
            x509.AuthorityKeyIdentifier.from_issuer_public_key(
                 self.ca_public_key
                 ),
            critical=False,
        )

        cert = builder.sign(self.ca_key, hashes.SHA256(), default_backend())

        return cert.public_bytes(serialization.Encoding.PEM)
Example #5
0
 def setUp(self):
     self.example_xml_files = (os.path.join(os.path.dirname(__file__), "example.xml"),
                               os.path.join(os.path.dirname(__file__), "example2.xml"))
     self.keys = dict(hmac=b"secret",
                      rsa=rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()),
                      dsa=dsa.generate_private_key(key_size=1024, backend=default_backend()),
                      ecdsa=ec.generate_private_key(curve=ec.SECP384R1(), backend=default_backend()))
Example #6
0
    def __init__(self, secret, algorithm=None):
        if algorithm is None:
            algorithm = DEFAULT_SIGN_ALGORITHM

        assert algorithm in ALGORITHMS, "Unknown algorithm"
        if isinstance(secret, six.string_types): secret = secret.encode("ascii")

        self._rsa_public = None
        self._rsa_private = None
        self._hash = None
        self.sign_algorithm, self.hash_algorithm = algorithm.split('-')

        if self.sign_algorithm == 'rsa':

            try:
                self._rsahash = HASHES[self.hash_algorithm]
                self._rsa_private = serialization.load_pem_private_key(secret,
                                                                       None,
                                                                       backend=default_backend())
                self._rsa_public = self._rsa_private.public_key()
            except ValueError as e:
                try:
                    self._rsa_public = serialization.load_pem_public_key(secret,
                                                                         backend=default_backend())
                except ValueError as e:
                    raise HttpSigException("Invalid key.")

        elif self.sign_algorithm == 'hmac':

            self._hash = hmac.HMAC(secret,
                                   HASHES[self.hash_algorithm](),
                                   backend=default_backend())
Example #7
0
def getPublicKey(registry=None):
    ''' Return the user's public key (generating and saving a new key pair if necessary) '''
    registry = registry or Registry_Base_URL
    pubkey_pem = None
    if _isPublicRegistry(registry):
        pubkey_pem = settings.getProperty('keys', 'public')
    else:
        for s in _getSources():
            if _sourceMatches(s, registry):
                if 'keys' in s and s['keys'] and 'public' in s['keys']:
                    pubkey_pem = s['keys']['public']
                    break
    if not pubkey_pem:
        pubkey_pem, privatekey_pem = _generateAndSaveKeys()
    else:
        # settings are unicode, we should be able to safely decode to ascii for
        # the key though, as it will either be hex or PEM encoded:
        pubkey_pem = pubkey_pem.encode('ascii')
    # if the key doesn't look like PEM, it might be hex-encided-DER (which we
    # used historically), so try loading that:
    if b'-----BEGIN PUBLIC KEY-----' in pubkey_pem:
        pubkey = serialization.load_pem_public_key(pubkey_pem, default_backend())
    else:
        pubkey_der = binascii.unhexlify(pubkey_pem)
        pubkey = serialization.load_der_public_key(pubkey_der, default_backend())
    return _pubkeyWireFormat(pubkey)
Example #8
0
    def encrypt(keyBits, plainData, params):
        """
        Encrypt the plainData using the keyBits according the encrypt params.

        :param Blob keyBits: The key value.
        :param Blob plainData: The data to encrypt.
        :param EncryptParams params: This encrypts according to
          params.getAlgorithmType() and other params as needed such as
          params.getInitialVector().
        :return: The encrypted data.
        :rtype: Blob
        """
        # For the cryptography package, we have to do the padding.
        padLength = 16 - (plainData.size() % 16)
        if sys.version_info[0] <= 2:
            pad = chr(padLength) * padLength
        else:
            pad = bytes([padLength]) * padLength

        if params.getAlgorithmType() == EncryptAlgorithmType.AesEcb:
            cipher = Cipher(algorithms.AES(
              keyBits.toBytes()), modes.ECB(), backend = default_backend())
        elif params.getAlgorithmType() == EncryptAlgorithmType.AesCbc:
            cipher = Cipher(algorithms.AES(
              keyBits.toBytes()), modes.CBC(params.getInitialVector().toBytes()),
              backend = default_backend())
        else:
            raise RuntimeError("unsupported encryption mode")

        encryptor = cipher.encryptor()
        return Blob(
          encryptor.update(plainData.toBytes() + pad) + encryptor.finalize(),
          False)
Example #9
0
    def decrypt(keyBits, encryptedData, params):
        """
        Decrypt the encryptedData using the keyBits according the encrypt params.

        :param Blob keyBits: The key value.
        :param Blob encryptedData: The data to decrypt.
        :param EncryptParams params: This decrypts according to
          params.getAlgorithmType() and other params as needed such as
          params.getInitialVector().
        :return: The decrypted data.
        :rtype: Blob
        """
        if params.getAlgorithmType() == EncryptAlgorithmType.AesEcb:
            cipher = Cipher(algorithms.AES(
              keyBits.toBytes()), modes.ECB(), backend = default_backend())
        elif params.getAlgorithmType() == EncryptAlgorithmType.AesCbc:
            cipher = Cipher(algorithms.AES(
              keyBits.toBytes()), modes.CBC(params.getInitialVector().toBytes()),
              backend = default_backend())
        else:
            raise RuntimeError("unsupported encryption mode")

        # For the cryptography package, we have to remove the padding.
        decryptor = cipher.decryptor()
        resultWithPad = decryptor.update(encryptedData.toBytes()) + decryptor.finalize()
        if sys.version_info[0] <= 2:
            padLength = ord(resultWithPad[-1])
        else:
            padLength = resultWithPad[-1]

        return Blob(resultWithPad[:-padLength], False)
Example #10
0
    def test_encode_decode_with_rsa_sha512(self):
        # PEM-formatted RSA key
        with open('tests/testkey_rsa', 'r') as rsa_priv_file:
            priv_rsakey = load_pem_private_key(ensure_bytes(rsa_priv_file.read()),
                                               password=None, backend=default_backend())
            jwt_message = jwt.encode(self.payload, priv_rsakey,
                                     algorithm='RS512')

        with open('tests/testkey_rsa.pub', 'r') as rsa_pub_file:
            pub_rsakey = load_ssh_public_key(ensure_bytes(rsa_pub_file.read()),
                                             backend=default_backend())
            assert jwt.decode(jwt_message, pub_rsakey)

            load_output = jwt.load(jwt_message)
            jwt.verify_signature(key=pub_rsakey, *load_output)

        # string-formatted key
        with open('tests/testkey_rsa', 'r') as rsa_priv_file:
            priv_rsakey = rsa_priv_file.read()
            jwt_message = jwt.encode(self.payload, priv_rsakey,
                                     algorithm='RS512')

        with open('tests/testkey_rsa.pub', 'r') as rsa_pub_file:
            pub_rsakey = rsa_pub_file.read()
            assert jwt.decode(jwt_message, pub_rsakey)

            load_output = jwt.load(jwt_message)
            jwt.verify_signature(key=pub_rsakey, *load_output)
Example #11
0
    def test_encode_decode_with_ecdsa_sha384(self):

        # PEM-formatted EC key
        with open('tests/testkey_ec', 'r') as ec_priv_file:
            priv_eckey = load_pem_private_key(ensure_bytes(ec_priv_file.read()),
                                              password=None, backend=default_backend())
            jwt_message = jwt.encode(self.payload, priv_eckey,
                                     algorithm='ES384')

        with open('tests/testkey_ec.pub', 'r') as ec_pub_file:
            pub_eckey = load_pem_public_key(ensure_bytes(ec_pub_file.read()),
                                            backend=default_backend())
            assert jwt.decode(jwt_message, pub_eckey)

            load_output = jwt.load(jwt_message)
            jwt.verify_signature(key=pub_eckey, *load_output)

        # string-formatted key
        with open('tests/testkey_ec', 'r') as ec_priv_file:
            priv_eckey = ec_priv_file.read()
            jwt_message = jwt.encode(self.payload, priv_eckey,
                                     algorithm='ES384')

        with open('tests/testkey_ec.pub', 'r') as ec_pub_file:
            pub_rsakey = ec_pub_file.read()
            assert jwt.decode(jwt_message, pub_eckey)

            load_output = jwt.load(jwt_message)
            jwt.verify_signature(key=pub_eckey, *load_output)
Example #12
0
    def generatePrivateKey(keyParams):
        """
        Generate a key pair according to keyParams and return a new
        TpmPrivateKey with the private key. You can get the public key with
        derivePublicKey.

        :param KeyParams keyParams: The parameters of the key.
        :return: A new TpmPrivateKey.
        :rtype: TpmPrivateKey
        :raises ValueError: If the key type is not supported.
        :raises TpmPrivateKey.Error: For an invalid key size, or an error
          generating.
        """
        if (keyParams.getKeyType() == KeyType.RSA or
            keyParams.getKeyType() == KeyType.EC):
            if keyParams.getKeyType() == KeyType.RSA:
                privateKey = rsa.generate_private_key(
                  public_exponent = 65537, key_size = keyParams.getKeySize(),
                  backend = default_backend())
            else:
                privateKey = ec.generate_private_key(
                  TpmPrivateKey._getEcCurve(keyParams.getKeySize()),
                  default_backend())
        else:
            raise ValueError(
              "Cannot generate a key pair of type " + str(keyParams.getKeyType()))

        result = TpmPrivateKey()
        result._privateKey = privateKey
        result._keyType = keyParams.getKeyType()

        return result
Example #13
0
    def test_generate_cert_key_pair(self):
        cn = 'testCN'
        bit_length = 512

        # Attempt to generate a cert/key pair
        cert_object = self.cert_generator.generate_cert_key_pair(
            cn=cn,
            validity=2 * 365 * 24 * 60 * 60,
            bit_length=bit_length,
            passphrase=self.ca_private_key_passphrase,
            ca_cert=self.ca_certificate,
            ca_key=self.ca_private_key,
            ca_key_pass=self.ca_private_key_passphrase
        )

        # Validate that the cert and key are loadable
        cert = x509.load_pem_x509_certificate(
            data=cert_object.certificate, backend=backends.default_backend())
        self.assertIsNotNone(cert)

        key = serialization.load_pem_private_key(
            data=cert_object.private_key,
            password=cert_object.private_key_passphrase,
            backend=backends.default_backend())
        self.assertIsNotNone(key)
Example #14
0
    def _format_public_key(self, key):
        if isinstance(key, str):
            jwkey = json_decode(key)
            if 'kty' not in jwkey:
                raise ValueError('Invalid key, missing "kty" attribute')
            if jwkey['kty'] == 'RSA':
                pubnum = rsa.RSAPublicNumbers(jwkey['e'], jwkey['n'])
                pubkey = pubnum.public_key(default_backend())
            elif jwkey['kty'] == 'EC':
                if jwkey['crv'] == 'P-256':
                    curve = ec.SECP256R1
                elif jwkey['crv'] == 'P-384':
                    curve = ec.SECP384R1
                elif jwkey['crv'] == 'P-521':
                    curve = ec.SECP521R1
                else:
                    raise TypeError('Unsupported Elliptic Curve')
                pubnum = ec.EllipticCurvePublicNumbers(
                    jwkey['x'], jwkey['y'], curve)
                pubkey = pubnum.public_key(default_backend())
            else:
                raise ValueError('Unknown key type: %s' % jwkey['kty'])
        elif isinstance(key, rsa.RSAPublicKey):
            pubkey = key
        elif isinstance(key, ec.EllipticCurvePublicKey):
            pubkey = key
        else:
            raise TypeError('Unknown key type: %s' % type(key))

        return pubkey.public_bytes(
            encoding=serialization.Encoding.DER,
            format=serialization.PublicFormat.SubjectPublicKeyInfo)
Example #15
0
def load_certificate(path):
    _, ext = os.path.splitext(path)
    with open(path, "rb") as f:
        if ext == ".pem":
            return x509.load_pem_x509_certificate(f.read(), default_backend())
        else:
            return x509.load_der_x509_certificate(f.read(), default_backend())
Example #16
0
def prepare_key(key_path, key_type=None):
    if key_type is None:
        key_type = 'pub'

    try:
        assert key_type.strip().lower() in PUB_TYPES + PRIV_TYPES
    except:
        raise ValueError("The type of key is not qualified. " + key_type)

    if key_type in PUB_TYPES:
        with open(key_path, 'rb') as pk_stream:
            key = serialization.load_ssh_public_key(
                data=pk_stream.read(),
                backend=default_backend()
            )
    elif key_type in PRIV_TYPES:
        with open(key_path, 'rb') as sk_stream:
            key = serialization.load_pem_private_key(
                data=sk_stream.read(),
                password=None,
                backend=default_backend()
            )
    else:
        key = None
    return key
Example #17
0
def sign_update_sparkle(dmg, dsaprivpem):
    """
    Signs the Darwin dmg and returns the base64 encoded hash.

    This replaces the functionality in:
    https://github.com/brave/Sparkle/blob/master/bin/sign_update

    Need to run the equivalent of the command:
    `$openssl dgst -sha1 -binary < "$1" | $openssl dgst -sha1 -sign "$2" | $openssl enc -base64`
    """

    import base64
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes, serialization
    from cryptography.hazmat.primitives.asymmetric import padding

    digest = hashes.Hash(hashes.SHA1(), backend=default_backend())
    sha1digest = None

    with open(dmg, 'rb') as dmg:
        with open(dsaprivpem, 'rb') as key:
            dmgcontent = dmg.read()
            digest.update(dmgcontent)
            sha1digest = digest.finalize()

            private_key = serialization.load_pem_private_key(key.read(), password=None,
                                                             backend=default_backend())
            signature = private_key.sign(sha1digest, hashes.SHA1())
            encoded_sign = base64.encodestring(signature)

    if sha1digest is not None:
        return encoded_sign
Example #18
0
def issue_certificate(csr, options):
    csr = x509.load_pem_x509_csr(csr, default_backend())

    builder = x509.CertificateBuilder(
        issuer_name=x509.Name([
            x509.NameAttribute(
                x509.OID_ORGANIZATION_NAME,
                options['authority'].authority_certificate.issuer
            )]
        ),
        subject_name=csr.subject,
        public_key=csr.public_key(),
        not_valid_before=options['validity_start'],
        not_valid_after=options['validity_end'],
        extensions=csr.extensions)

    # TODO figure out a better way to increment serial
    builder = builder.serial_number(int(uuid.uuid4()))

    private_key = serialization.load_pem_private_key(
        options['authority'].authority_certificate.private_key,
        password=None,
        backend=default_backend()
    )

    cert = builder.sign(private_key, hashes.SHA256(), default_backend())

    return cert.public_bytes(
        encoding=serialization.Encoding.PEM
    )
Example #19
0
def generate_csr_and_key(common_name):
    """Return a dict with a new csr, public key and private key."""
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend())

    public_key = private_key.public_key()

    csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
        x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, common_name),
    ])).sign(private_key, hashes.SHA256(), default_backend())

    result = {
        'csr': csr.public_bytes(
            encoding=serialization.Encoding.PEM).decode("utf-8"),
        'private_key': private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()).decode("utf-8"),
        'public_key': public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo).decode(
                "utf-8"),
    }

    return result
Example #20
0
    def generate_key(self, slot, algorithm, pin_policy=PIN_POLICY.DEFAULT,
                     touch_policy=TOUCH_POLICY.DEFAULT):

        if ALGO.is_rsa(algorithm):
            ensure_not_cve201715361_vulnerable_firmware_version(self.version)

        if algorithm not in self.supported_algorithms:
            raise UnsupportedAlgorithm(
                'Algorithm not supported on this YubiKey: {}'
                .format(algorithm),
                algorithm_id=algorithm)

        data = Tlv(TAG.ALGO, six.int2byte(algorithm))
        if pin_policy:
            data += Tlv(TAG.PIN_POLICY, six.int2byte(pin_policy))
        if touch_policy:
            data += Tlv(TAG.TOUCH_POLICY, six.int2byte(touch_policy))
        data = Tlv(0xac, data)
        resp = self.send_cmd(INS.GENERATE_ASYMMETRIC, 0, slot, data)
        if algorithm in [ALGO.RSA1024, ALGO.RSA2048]:
            data = _parse_tlv_dict(Tlv(resp[1:]).value)
            return rsa.RSAPublicNumbers(
                int_from_bytes(data[0x82], 'big'),
                int_from_bytes(data[0x81], 'big')
            ).public_key(default_backend())
        elif algorithm in [ALGO.ECCP256, ALGO.ECCP384]:
            curve = ec.SECP256R1 if algorithm == ALGO.ECCP256 else ec.SECP384R1
            return ec.EllipticCurvePublicNumbers.from_encoded_point(
                curve(),
                resp[5:]
            ).public_key(default_backend())

        raise UnsupportedAlgorithm(
            'Invalid algorithm: {}'.format(algorithm),
            algorithm_id=algorithm)
Example #21
0
    def download_crt(self, key=None):
        one_day = datetime.timedelta(1, 0, 0)

        private_key = serialization.load_pem_private_key(
            key,
            password=None,
            backend=default_backend()
        )

        public_key = private_key.public_key()

        builder = x509.CertificateBuilder()
        builder = builder.subject_name(x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, self.domain),
        ]))
        builder = builder.issuer_name(x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, self.domain),
        ]))
        builder = builder.not_valid_before(datetime.datetime.today() - one_day)
        builder = builder.not_valid_after(datetime.datetime(2018, 8, 2))
        builder = builder.serial_number(int(uuid.uuid4()))
        builder = builder.public_key(public_key)
        builder = builder.add_extension(
            x509.BasicConstraints(ca=False, path_length=None), critical=True,
        )
        certificate = builder.sign(
            private_key=private_key, algorithm=hashes.SHA256(),
            backend=default_backend()
        )

        return certificate.public_bytes(serialization.Encoding.PEM)
Example #22
0
        def generate_self_signed_cert(cert_file, key_file):
            """Given two file-like objects, generate an SSL key and certificate."""
            one_day = datetime.timedelta(1, 0, 0)
            private_key = rsa.generate_private_key(
                public_exponent=65537,
                key_size=2048,
                backend=default_backend()
            )
            public_key = private_key.public_key()
            builder = x509.CertificateBuilder()
            builder = builder.subject_name(x509.Name([
                x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
            ]))
            builder = builder.issuer_name(x509.Name([
                x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
            ]))
            builder = builder.not_valid_before(datetime.datetime.today() - one_day)
            builder = builder.not_valid_after(datetime.datetime.today() + datetime.timedelta(365*10))
            builder = builder.serial_number(int(uuid.uuid4()))
            builder = builder.public_key(public_key)
            builder = builder.add_extension(
                x509.BasicConstraints(ca=False, path_length=None), critical=True,
            )
            certificate = builder.sign(
                private_key=private_key, algorithm=hashes.SHA256(),
                backend=default_backend()
            )

            key_file.write(private_key.private_bytes(
                Encoding.PEM, 
                PrivateFormat.TraditionalOpenSSL,
                NoEncryption()
            ))
            cert_file.write(certificate.public_bytes(Encoding.PEM))
Example #23
0
    def new_cipher(self, key, iv, digest=None):
        """
        @param key:    the secret key, a byte string
        @param iv:     the initialization vector, a byte string. Used as the
                       initial nonce in counter mode
        @param digest: also known as tag or icv. A byte string containing the
                       digest of the encrypted data. Only use this during
                       decryption!

        @return:    an initialized cipher object for this algo
        """
        if type(key) is str:
            key = key.encode('ascii')
        if self.is_aead and digest is not None:
            # With AEAD, the mode needs the digest during decryption.
            return Cipher(
                self.cipher(key),
                self.mode(iv, digest, len(digest)),
                default_backend(),
            )
        else:
            return Cipher(
                self.cipher(key),
                self.mode(iv),
                default_backend(),
            )
Example #24
0
    def scan(self, offset=0, maxlen=None):
        for hit in super(CertScanner, self).scan(offset=offset, maxlen=maxlen):
            signature = self.address_space.read(hit + 4, 3)
            size = self.profile.Object(
                "unsigned be short", offset=hit+2, vm=self.address_space)
            description = None

            if signature.startswith(b"\x30\x82"):
                data = self.address_space.read(hit, size + 4)
                if x509:
                    try:
                        cert = x509.load_der_x509_certificate(data, default_backend())
                        description = dict((
                            attr.oid._name, attr.value) for attr in cert.subject)
                    except Exception:
                        pass

                yield hit, "X509", data, description

            elif signature.startswith(b"\x02\x01\x00"):
                data = self.address_space.read(hit, size + 4)
                if x509:
                    try:
                        pem = (b"-----BEGIN RSA PRIVATE KEY-----\n" +
                               base64.b64encode(data) +
                               b"-----END RSA PRIVATE KEY-----")
                        key = serialization.load_pem_private_key(
                            pem, password=None, backend=default_backend())
                        description = ""
                    except Exception:
                        pass

                yield hit, "RSA", data, description
Example #25
0
def main():
	message = 'This is my benchmarking message; it should really be longer'
	e1 = time.time()
	#Time key generation: EC
	eck1 = ec.generate_private_key(ec.SECP384R1(), default_backend())
	eck2 = ec.generate_private_key(ec.SECP384R1(), default_backend())
	e2 = time.time()
	#Time key generation: RSA
	rsak = rsa.generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend())
	e3 = time.time()
	#Time Encryption: EC
	ecct = transport_security.construct_message(message, srcprivkey=eck1, destpubkey=eck2.public_key())
	e4 = time.time()
	#Time Encryption: RSA
	rsact = transport_security.get_raw_encrypted(message, pubkey=rsak.public_key())
	e5 = time.time()
	#Time Decryption: EC
	ecpt = transport_security.deconstruct_message(message_dict=ecct, destprivkey=eck2, srcpubkey=eck1.public_key())
	e6 = time.time()
	if ecpt == message:
		print("EC Decryption successful")
	else:
		print("EC Decryption failed")
	#Time Decryption: RSA
	rsapt = transport_security.get_raw_decrypted(ciphertext=rsact, privkey=rsak)
	e7 = time.time()
	if ecpt == message:
		print("RSA Decryption successful")
	else:
		print("RSA Decryption failed")

	with open('timing.out', 'a') as f:
		record = "{}\t{}\t{}\t{}\t{}\t{}\n".format(e2-e1, e3-e2, e4-e3, e5-e4, e6-e5, e7-e6)
		f.write(record)
def regenerate_certificate_revocation_list(self, certification_authority):
    logger.info("Updating CRL for CA %s" % certification_authority.common_name)
    one_day = datetime.timedelta(1, 0, 0)
    ca_cert =  x509.load_pem_x509_certificate(str(certification_authority.certificate), default_backend())
    ca_key =  serialization.load_pem_private_key(str(certification_authority.private_key), None, default_backend())

    builder = x509.CertificateRevocationListBuilder()
    builder = builder.issuer_name(ca_cert.subject)
    builder = builder.last_update(datetime.datetime.today())
    builder = builder.next_update(datetime.datetime.today() + one_day)

    for certificate in SSLRevokedCertificate.objects.filter(certification_authority=certification_authority):
        logger.info("Adding certificate 0x%X" % certificate.serial_number)
        revoked_cert = x509.RevokedCertificateBuilder().serial_number(
            certificate.serial_number
        ).revocation_date(
            certificate.revocation_date.replace(tzinfo=None)
        ).build(default_backend())

        builder = builder.add_revoked_certificate(revoked_cert)
    crl = builder.sign(
        private_key=ca_key, algorithm=hashes.SHA256(),
        backend=default_backend()
    )

    logger.info('Saving models')
    certification_authority.revocation_list = crl.public_bytes(serialization.Encoding.PEM)
    print certification_authority.revocation_list
    certification_authority.save()
Example #27
0
    def verify_hit(self, hit, address_space):
        signature = address_space.read(hit + 4, 3)
        size = self.profile.Object(
            "unsigned be short", offset=hit+2, vm=address_space)
        description = None

        if signature.startswith(b"\x30\x82"):
            data = address_space.read(hit, size + 4)
            if x509:
                try:
                    cert = x509.load_der_x509_certificate(data, default_backend())
                    description = dict((
                        attr.oid._name, attr.value) for attr in cert.subject)
                except Exception:
                    pass

            return "X509", data, description

        elif signature.startswith(b"\x02\x01\x00"):
            data = address_space.read(hit, size + 4)
            if x509:
                try:
                    pem = (b"-----BEGIN RSA PRIVATE KEY-----\n" +
                           base64.b64encode(data) +
                           b"-----END RSA PRIVATE KEY-----")
                    key = serialization.load_pem_private_key(
                        pem, password=None, backend=default_backend())
                    description = ""
                except Exception:
                    pass

            return "RSA", data, description

        return None, None, None
Example #28
0
    def test_works_with_lowercase_attr_type_shortname(self, generator):
        principal = {
            'uid': ['testuser'],
            'mail': ['*****@*****.**'],
        }
        template_env = {
            'ipacertificatesubjectbase': [
                'o=DOMAIN.EXAMPLE.COM'  # lower-case attr type shortname
            ],
        }
        config = generator.csr_config(principal, template_env, 'userCert')

        key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend(),
        )
        adaptor = csrgen.OpenSSLAdaptor(key=key)

        reqinfo = bytes(csrgen_ffi.build_requestinfo(
            config.encode('utf-8'), adaptor.get_subject_public_key_info()))
        csr_der = adaptor.sign_csr(reqinfo)
        csr = x509.load_der_x509_csr(csr_der, default_backend())
        assert (
            csr.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME)
            == [x509.NameAttribute(x509.NameOID.COMMON_NAME, u'testuser')]
        )
        assert (
            csr.subject.get_attributes_for_oid(x509.NameOID.ORGANIZATION_NAME)
            == [x509.NameAttribute(
                x509.NameOID.ORGANIZATION_NAME, u'DOMAIN.EXAMPLE.COM')]
        )
Example #29
0
    def update(self, data):
        self.buf += data
        if self.cipher is None:
            if len(self.buf) < 8:
                return b""
            if self.buf[0:6] != FILEMAGIC:
                raise EncryptorError("Invalid magic bytes")
            cipherkeylen = struct.unpack(">H", self.buf[6:8])[0]
            if len(self.buf) < 8 + cipherkeylen:
                return b""
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            try:
                plainkey = self.rsa_private_key.decrypt(self.buf[8:8 + cipherkeylen], pad)
            except AssertionError:
                raise EncryptorError("Decrypting key data failed")
            if len(plainkey) != 64:
                raise EncryptorError("Integrity check failed")
            key = plainkey[0:16]
            nonce = plainkey[16:32]
            auth_key = plainkey[32:64]

            self.cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).decryptor()
            self.authenticator = HMAC(auth_key, SHA256(), backend=default_backend())
            self.buf = self.buf[8 + cipherkeylen:]

        if len(self.buf) < 32:
            return b""

        self.authenticator.update(self.buf[:-32])
        result = self.cipher.update(self.buf[:-32])
        self.buf = self.buf[-32:]

        return result
Example #30
0
    def sign_csr_builder(self, slot, public_key, builder, touch_callback=None):
        algorithm = ALGO.from_public_key(public_key)
        dummy_key = _dummy_key(algorithm)
        csr = builder.sign(dummy_key, hashes.SHA256(), default_backend())
        seq = parse_tlvs(Tlv(csr.public_bytes(Encoding.DER)).value)

        # Replace public key
        pub_format = PublicFormat.PKCS1 if algorithm.name.startswith('RSA') \
            else PublicFormat.SubjectPublicKeyInfo
        dummy_bytes = dummy_key.public_key().public_bytes(
            Encoding.DER, pub_format)
        pub_bytes = public_key.public_bytes(Encoding.DER, pub_format)
        seq[0] = seq[0].replace(dummy_bytes, pub_bytes)

        if touch_callback is not None:
            touch_timer = Timer(0.500, touch_callback)
            touch_timer.start()

        sig = self.sign(slot, algorithm, seq[0])

        if touch_callback is not None:
            touch_timer.cancel()

        # Replace signature, add unused bits = 0
        seq[2] = Tlv(seq[2].tag, b'\0' + sig)
        # Re-assemble sequence
        der = Tlv(0x30, b''.join(seq))

        return x509.load_der_x509_csr(der, default_backend())
Example #31
0
 def serialize(self):
     rsa_pub = self.public_key(default_backend())
     return (rsa_pub.public_bytes(
         encoding=serialization.Encoding.PEM,
         format=serialization.PublicFormat.SubjectPublicKeyInfo))
Example #32
0
def load_csr(data):
    """
    Loads a PEM X.509 CSR.
    """
    return x509.load_pem_x509_csr(data, default_backend())
Example #33
0
def read_public_key(public_key_pem):
    with open(public_key_pem, "rb") as key_file:
        private_key = serialization.load_pem_public_key(
            key_file.read(), backend=default_backend())
    return private_key
Example #34
0
 def key_from_pem(self, pem):
     "Get the EC from a public PEM."
     return serialization.load_pem_public_key(pem,
                                              backend=default_backend())
Example #35
0
from paramiko import py3compat

from sshaolin import common
from sshaolin.models import CommandResponse

# this is a hack to preimport dependencies imported in a thread during connect
# which causes a deadlock. https://github.com/paramiko/paramiko/issues/104
py3compat.u("".encode())

# dirty hack 2.0 also issue 104
# Try / Catch to prevent users using paramiko<2.0.0 from raising an ImportError
try:
    from cryptography.hazmat.backends import default_backend
    from cryptography.utils import int_from_bytes
    int_from_bytes(b"a", "big")
    default_backend()
except ImportError:
    pass


class CommandOperationTimeOut(socket.timeout):
    pass


class ProxyTypes(object):
    SOCKS5 = 2
    SOCKS4 = 1


def read_pipe(pipe, fp_out):
    def target():
Example #36
0
 def get_certificate_as_certificate(self):
     """
     Retrieves the certificate as a cryptography.x509.Certificate
     """
     return x509.load_pem_x509_certificate(
         self.certificate_and_private_key['certificate'], default_backend())
Example #37
0
 def deserialize(self, data):
     key = serialization.load_pem_public_key(data, default_backend())
     self._e = key.public_numbers().e
     self._n = key.public_numbers().n
Example #38
0
 def _encrypt_RSA(self, modulus, passphrase, text):
     public_numbers = rsa.RSAPublicNumbers(passphrase, modulus)
     public_key = public_numbers.public_key(default_backend())
     ciphertext = public_key.encrypt(text.encode('ascii'),
                                     padding.PKCS1v15())
     return ciphertext
Example #39
0
class TtypePushAPITestCase(MyApiTestCase):
    """
    test /ttype/push
    """

    server_private_key = rsa.generate_private_key(public_exponent=65537,
                                                  key_size=4096,
                                                  backend=default_backend())
    server_private_key_pem = to_unicode(
        server_private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()))
    server_public_key_pem = to_unicode(
        server_private_key.public_key().public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo))

    # We now allow white spaces in the firebase config name
    firebase_config_name = "my firebase config"

    smartphone_private_key = rsa.generate_private_key(
        public_exponent=65537, key_size=4096, backend=default_backend())
    smartphone_public_key = smartphone_private_key.public_key()
    smartphone_public_key_pem = to_unicode(
        smartphone_public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo))
    # The smartphone sends the public key in URLsafe and without the ----BEGIN header
    smartphone_public_key_pem_urlsafe = strip_key(
        smartphone_public_key_pem).replace("+", "-").replace("/", "_")
    serial_push = "PIPU001"

    def _create_push_token(self):
        tparams = {'type': 'push', 'genkey': 1}
        tparams.update(FB_CONFIG_VALS)
        tok = init_token(param=tparams)
        tok.add_tokeninfo(PUSH_ACTION.FIREBASE_CONFIG,
                          self.firebase_config_name)
        tok.add_tokeninfo(PUBLIC_KEY_SMARTPHONE,
                          self.smartphone_public_key_pem_urlsafe)
        tok.add_tokeninfo('firebase_token', 'firebaseT')
        tok.add_tokeninfo(PUBLIC_KEY_SERVER, self.server_public_key_pem)
        tok.add_tokeninfo(PRIVATE_KEY_SERVER, self.server_private_key_pem,
                          'password')
        tok.del_tokeninfo("enrollment_credential")
        tok.token.rollout_state = "enrolled"
        tok.token.active = True
        return tok

    def test_00_create_realms(self):
        self.setUp_user_realms()

    def test_01_api_enroll_push(self):
        self.authenticate()

        # Failed enrollment due to missing policy
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertNotEqual(res.status_code, 200)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "Missing enrollment policy for push token: push_firebase_configuration"
            )
            self.assertEqual(error.get("code"), 303)

        r = set_smsgateway(
            self.firebase_config_name,
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", FB_CONFIG_VALS)
        self.assertTrue(r > 0)
        set_policy("push1",
                   scope=SCOPE.ENROLL,
                   action="{0!s}={1!s}".format(PUSH_ACTION.FIREBASE_CONFIG,
                                               self.firebase_config_name))

        # 1st step
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code, 200)
            detail = res.json.get("detail")
            serial = detail.get("serial")
            self.assertEqual(detail.get("rollout_state"), "clientwait")
            self.assertTrue("pushurl" in detail)
            # check that the new URL contains the serial number
            self.assertTrue(
                "&serial=PIPU" in detail.get("pushurl").get("value"))
            self.assertTrue("appid=" in detail.get("pushurl").get("value"))
            self.assertTrue("appidios=" in detail.get("pushurl").get("value"))
            self.assertTrue("apikeyios=" in detail.get("pushurl").get("value"))
            self.assertFalse("otpkey" in detail)
            enrollment_credential = detail.get("enrollment_credential")

        # 2nd step. Failing with wrong serial number
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "serial": "wrongserial",
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 404, res)
            status = res.json.get("result").get("status")
            self.assertFalse(status)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "No token with this serial number in the rollout state 'clientwait'."
            )

        # 2nd step. Fails with missing enrollment credential
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "serial": serial,
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT",
                    "enrollment_credential": "WRonG"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 400, res)
            status = res.json.get("result").get("status")
            self.assertFalse(status)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "ERR905: Invalid enrollment credential. You are not authorized to finalize this token."
            )

        # 2nd step: as performed by the smartphone
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "enrollment_credential": enrollment_credential,
                    "serial": serial,
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            detail = res.json.get("detail")
            # still the same serial number
            self.assertEqual(serial, detail.get("serial"))
            self.assertEqual(detail.get("rollout_state"), "enrolled")
            # Now the smartphone gets a public key from the server
            augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format(
                detail.get("public_key"))
            parsed_server_pubkey = serialization.load_pem_public_key(
                to_bytes(augmented_pubkey), default_backend())
            self.assertIsInstance(parsed_server_pubkey, rsa.RSAPublicKey)
            pubkey = detail.get("public_key")

            # Now check, what is in the token in the database
            toks = get_tokens(serial=serial)
            self.assertEqual(len(toks), 1)
            token_obj = toks[0]
            self.assertEqual(token_obj.token.rollout_state, u"enrolled")
            self.assertTrue(token_obj.token.active)
            tokeninfo = token_obj.get_tokeninfo()
            self.assertEqual(tokeninfo.get("public_key_smartphone"),
                             self.smartphone_public_key_pem_urlsafe)
            self.assertEqual(tokeninfo.get("firebase_token"), u"firebaseT")
            self.assertEqual(
                tokeninfo.get("public_key_server").strip().strip(
                    "-BEGIN END RSA PUBLIC KEY-").strip(), pubkey)
            # The token should also contain the firebase config
            self.assertEqual(tokeninfo.get(PUSH_ACTION.FIREBASE_CONFIG),
                             self.firebase_config_name)
            # remove the token
            remove_token(serial)

    def test_02_api_push_poll(self):
        r = set_smsgateway(
            self.firebase_config_name,
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", FB_CONFIG_VALS)
        self.assertGreater(r, 0)

        # create a new push token
        tokenobj = self._create_push_token()
        serial = tokenobj.get_serial()

        # set PIN
        tokenobj.set_pin("pushpin")
        tokenobj.add_user(User("cornelius", self.realm1))

        # We mock the ServiceAccountCredentials, since we can not directly contact the Google API
        with mock.patch(
                'privacyidea.lib.smsprovider.FirebaseProvider.service_account.Credentials'
                '.from_service_account_file') as mySA:
            # alternative: side_effect instead of return_value
            mySA.return_value = _create_credential_mock()

            # add responses, to simulate the communication to firebase
            responses.add(
                responses.POST,
                'https://fcm.googleapis.com/v1/projects/test-123456/messages:send',
                body="""{}""",
                content_type="application/json")

            # Send the first authentication request to trigger the challenge.
            # No push notification is submitted to firebase, but a challenge is created anyway
            with self.app.test_request_context('/validate/check',
                                               method='POST',
                                               data={
                                                   "user": "******",
                                                   "realm": self.realm1,
                                                   "pass": "******"
                                               }):
                res = self.app.full_dispatch_request()
                self.assertTrue(res.status_code == 400, res)
                jsonresp = res.json
                self.assertFalse(jsonresp.get("result").get("status"))
                self.assertEqual(
                    jsonresp.get("result").get("error").get("code"), 401)
                self.assertEqual(
                    jsonresp.get("result").get("error").get("message"),
                    "ERR401: Failed to submit message to firebase service.")

        # first create a signature
        ts = datetime.utcnow().isoformat()
        sign_string = u"{serial}|{timestamp}".format(serial=serial,
                                                     timestamp=ts)
        sig = self.smartphone_private_key.sign(sign_string.encode('utf8'),
                                               padding.PKCS1v15(),
                                               hashes.SHA256())
        # now check that we receive the challenge when polling
        with self.app.test_request_context('/ttype/push',
                                           method='GET',
                                           data={
                                               "serial": serial,
                                               "timestamp": ts,
                                               "signature": b32encode(sig)
                                           }):
            res = self.app.full_dispatch_request()

            # check that the serial was set in flask g (via before_request in ttype.py)
            self.assertTrue(self.app_context.g.serial, serial)
            self.assertTrue(res.status_code == 200, res)
            self.assertTrue(res.json['result']['status'])
            chall = res.json['result']['value'][0]
            self.assertTrue(chall)

            challenge = chall["nonce"]
            # This is what the smartphone answers.
            # create the signature:
            sign_data = "{0!s}|{1!s}".format(challenge, serial)
            signature = b32encode_and_unicode(
                self.smartphone_private_key.sign(sign_data.encode("utf-8"),
                                                 padding.PKCS1v15(),
                                                 hashes.SHA256()))

            # Answer the challenge
            with self.app.test_request_context('/ttype/push',
                                               method='POST',
                                               data={
                                                   "serial": serial,
                                                   "nonce": challenge,
                                                   "signature": signature
                                               }):
                res = self.app.full_dispatch_request()
                self.assertTrue(res.status_code == 200, res)
                self.assertTrue(res.json['result']['status'])
                self.assertTrue(res.json['result']['value'])
Example #40
0
 def deserialize(self, data):
     cert = x509.load_pem_x509_certificate(data, default_backend())
     key_material = cert.public_key().public_numbers()
     self._e = key_material.e
     self._n = key_material.n
class ChainKeyKDF(KDF):
    """
    An implementations of the KDF interface based on a recommendation by WhisperSystems:

    HMAC with SHA-256 or SHA-512 is recommended, using ck as the HMAC key and using
    separate constants as input (e.g. a single byte 0x01 as input to produce the message
    key, and a single byte 0x02 as input to produce the next chain key).

    Notice: Following these recommendations, the calculate method ignored both the data
    and the length parameters.
    """

    CRYPTOGRAPHY_BACKEND = default_backend()

    HASH_FUNCTIONS = {
        "SHA-256": hashes.SHA256,
        "SHA-512": hashes.SHA512
    }

    def __init__(self, hash_function, ck_constant = b"\x02", mk_constant = b"\x01"):
        """
        Prepare a ChainKeyKDF, following a recommendation by WhisperSystems.

        :param hash_function: One of (the strings) "SHA-256" and "SHA-512".
        :param ck_constant: A single byte used for derivation of the next chain key.
        :param mk_constant: A single byte used for derivation of the next message key.
        """

        super(ChainKeyKDF, self).__init__()

        if not hash_function in ChainKeyKDF.HASH_FUNCTIONS:
            raise ValueError("Invalid value passed for the hash_function parameter.")

        if not isinstance(ck_constant, bytes):
            raise TypeError("Wrong type passed for the ck_constant parameter.")

        if len(ck_constant) != 1:
            raise ValueError("Invalid value passed for the ck_constant parameter.")

        if not isinstance(mk_constant, bytes):
            raise TypeError("Wrong type passed for the mk_constant parameter.")

        if len(mk_constant) != 1:
            raise ValueError("Invalid value passed for the mk_constant parameter.")

        self.__hash_function = ChainKeyKDF.HASH_FUNCTIONS[hash_function]
        self.__ck_constant = ck_constant
        self.__mk_constant = mk_constant
    
    def calculate(self, key, data = None, length = None):
        chain_key = hmac.HMAC(
            key,
            self.__hash_function(),
            backend = self.__class__.CRYPTOGRAPHY_BACKEND
        )

        chain_key.update(self.__ck_constant)

        message_key = hmac.HMAC(
            key,
            self.__hash_function(),
            backend = self.__class__.CRYPTOGRAPHY_BACKEND
        )

        message_key.update(self.__mk_constant)

        return chain_key.finalize() + message_key.finalize()
Example #42
0
 def setup_cipher(self):
     algorithm = algorithms.ARC4(self.key)
     self._cipher = Cipher(algorithm, mode=None, backend=default_backend())
     self.encryptor = self._cipher.encryptor()
     self.decryptor = self._cipher.decryptor()
Example #43
0
def nc_kdf(shared_secret, kep2, kep3) -> list:
    """
    Return a list of results from the kdf procedure.

    :param shared_secret: bytes
    :param kep2: bytes, sent by the dsc
    :param kep3: bytes, sent by the adv

    :return: list of results

    Kep2 might be containied in a single payload together with Kep1.

    Interesting return values:

        rv[6] = cli2ser_key: dsc (encrypt) --> adv (decrypt)
        rv[8] = ser2cli_key: adv (encrypt) --> dsc (decrypt)
        rv[9] = auth token

    """
    validate_shared_secret("nc_kdf", shared_secret)
    validate_kep2("nc_kdf", kep2)
    validate_kep3("nc_kdf", kep3)

    rv = []

    kdf1 = Hash(SHA256(), backend=default_backend())
    kdf1.update(shared_secret)
    kdf1_out = kdf1.finalize()
    # log.debug("nc_kdf kdf1_out: {}, {}".format(kdf1_out, type(kdf1_out)))
    rv.append(kdf1_out)

    kdf2 = HMAC(NC_STR_UKEY2v1auth, SHA256(), backend=default_backend())
    kdf2.update(kdf1_out)
    kdf2_out = kdf2.finalize()
    # log.debug("nc_kdf kdf2_out: {}, {}".format(kdf2_out, type(kdf2_out)))
    rv.append(kdf2_out)

    kdf3 = HMAC(kdf2_out, SHA256(), backend=default_backend())
    kdf3_inp_hex = kep2[4:].hex() + kep3[4:].hex()
    # log.debug("nc_kdf kdf3_inp_hex: {}, {}".format(kdf3_inp_hex, len(kdf3_inp_hex)))
    kdf3_inp = unhexlify(kdf3_inp_hex)
    # NOTE: heuristic
    assert len(kdf3_inp) == 252 or len(kdf3_inp) == 253 or len(kdf3_inp) == 254
    kdf3.update(kdf3_inp)
    kdf3.update(b'\x01')
    kdf3_out = kdf3.finalize()
    # log.debug("nc_kdf kdf3_out: {}, {}".format(kdf3_out, type(kdf3_out)))
    rv.append(kdf3_out)

    kdf4 = HMAC(NC_STR_UKEY2v1next, SHA256(), backend=default_backend())
    kdf4.update(kdf1_out)
    kdf4_out = kdf4.finalize()
    # log.debug("nc_kdf kdf4_out: {}, {}".format(kdf4_out, type(kdf4_out)))
    rv.append(kdf4_out)

    # NOTE: same inputs of kdf3
    kdf5 = HMAC(kdf4_out, SHA256(), backend=default_backend())
    kdf5.update(kdf3_inp)
    kdf5.update(b'\x01')
    kdf5_out = kdf5.finalize()
    # log.debug("nc_kdf kdf5_out: {}, {}".format(kdf5_out, type(kdf5_out)))
    rv.append(kdf5_out)

    kdf6 = HMAC(NC_KDF_KEY, SHA256(), backend=default_backend())
    kdf6.update(kdf5_out)
    kdf6_out = kdf6.finalize()
    # log.debug("nc_kdf kdf6_out: {}, {}".format(kdf6_out, type(kdf6_out)))
    rv.append(kdf6_out)

    # NOTE: computes cli2ser_key
    kdf7 = HMAC(kdf6_out, SHA256(), backend=default_backend())
    kdf7.update(NC_STR_CLIENT)
    kdf7.update(b'\x01')
    kdf7_out = kdf7.finalize()
    # log.debug("nc_kdf kdf7_out: {}, {}".format(kdf7_out, type(kdf7_out)))
    cli2ser_key = kdf7_out
    log.debug("nc_kdf cli2ser_key: {}, {}".format(kdf7_out, len(kdf7_out)))
    rv.append(kdf7_out)

    # NOTE: same as kdf6
    kdf8 = HMAC(NC_KDF_KEY, SHA256(), backend=default_backend())
    kdf8.update(kdf5_out)
    kdf8_out = kdf8.finalize()
    # log.debug("nc_kdf kdf8_out: {}, {}".format(kdf8_out, type(kdf8_out)))
    rv.append(kdf8_out)

    # NOTE: computes ser2cli_key
    kdf9 = HMAC(kdf8_out, SHA256(), backend=default_backend())
    kdf9.update(NC_STR_SERVER)
    kdf9.update(b'\x01')
    kdf9_out = kdf9.finalize()
    # log.debug("nc_kdf kdf9_out: {}, {}".format(kdf9_out, type(kdf9_out)))
    ser2cli_key = kdf9_out
    log.debug("nc_kdf ser2cli_key: {}, {}".format(kdf9_out, len(kdf9_out)))
    rv.append(kdf9_out)

    # NOTE: computes auth token from kdf3_out
    r_auth_token = b64encode(kdf3_out)[:5]
    auth_token = r_auth_token.decode('utf-8').upper()
    assert len(auth_token) == 5
    log.debug("nc_kdf auth_token: {}, {}".format(auth_token, len(auth_token)))
    rv.append(auth_token)

    return rv
Example #44
0
    def test_01_api_enroll_push(self):
        self.authenticate()

        # Failed enrollment due to missing policy
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertNotEqual(res.status_code, 200)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "Missing enrollment policy for push token: push_firebase_configuration"
            )
            self.assertEqual(error.get("code"), 303)

        r = set_smsgateway(
            self.firebase_config_name,
            u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider',
            "myFB", FB_CONFIG_VALS)
        self.assertTrue(r > 0)
        set_policy("push1",
                   scope=SCOPE.ENROLL,
                   action="{0!s}={1!s}".format(PUSH_ACTION.FIREBASE_CONFIG,
                                               self.firebase_config_name))

        # 1st step
        with self.app.test_request_context('/token/init',
                                           method='POST',
                                           data={
                                               "type": "push",
                                               "genkey": 1
                                           },
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertEqual(res.status_code, 200)
            detail = res.json.get("detail")
            serial = detail.get("serial")
            self.assertEqual(detail.get("rollout_state"), "clientwait")
            self.assertTrue("pushurl" in detail)
            # check that the new URL contains the serial number
            self.assertTrue(
                "&serial=PIPU" in detail.get("pushurl").get("value"))
            self.assertTrue("appid=" in detail.get("pushurl").get("value"))
            self.assertTrue("appidios=" in detail.get("pushurl").get("value"))
            self.assertTrue("apikeyios=" in detail.get("pushurl").get("value"))
            self.assertFalse("otpkey" in detail)
            enrollment_credential = detail.get("enrollment_credential")

        # 2nd step. Failing with wrong serial number
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "serial": "wrongserial",
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 404, res)
            status = res.json.get("result").get("status")
            self.assertFalse(status)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "No token with this serial number in the rollout state 'clientwait'."
            )

        # 2nd step. Fails with missing enrollment credential
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "serial": serial,
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT",
                    "enrollment_credential": "WRonG"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 400, res)
            status = res.json.get("result").get("status")
            self.assertFalse(status)
            error = res.json.get("result").get("error")
            self.assertEqual(
                error.get("message"),
                "ERR905: Invalid enrollment credential. You are not authorized to finalize this token."
            )

        # 2nd step: as performed by the smartphone
        with self.app.test_request_context(
                '/ttype/push',
                method='POST',
                data={
                    "enrollment_credential": enrollment_credential,
                    "serial": serial,
                    "pubkey": self.smartphone_public_key_pem_urlsafe,
                    "fbtoken": "firebaseT"
                }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            detail = res.json.get("detail")
            # still the same serial number
            self.assertEqual(serial, detail.get("serial"))
            self.assertEqual(detail.get("rollout_state"), "enrolled")
            # Now the smartphone gets a public key from the server
            augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format(
                detail.get("public_key"))
            parsed_server_pubkey = serialization.load_pem_public_key(
                to_bytes(augmented_pubkey), default_backend())
            self.assertIsInstance(parsed_server_pubkey, rsa.RSAPublicKey)
            pubkey = detail.get("public_key")

            # Now check, what is in the token in the database
            toks = get_tokens(serial=serial)
            self.assertEqual(len(toks), 1)
            token_obj = toks[0]
            self.assertEqual(token_obj.token.rollout_state, u"enrolled")
            self.assertTrue(token_obj.token.active)
            tokeninfo = token_obj.get_tokeninfo()
            self.assertEqual(tokeninfo.get("public_key_smartphone"),
                             self.smartphone_public_key_pem_urlsafe)
            self.assertEqual(tokeninfo.get("firebase_token"), u"firebaseT")
            self.assertEqual(
                tokeninfo.get("public_key_server").strip().strip(
                    "-BEGIN END RSA PUBLIC KEY-").strip(), pubkey)
            # The token should also contain the firebase config
            self.assertEqual(tokeninfo.get(PUSH_ACTION.FIREBASE_CONFIG),
                             self.firebase_config_name)
            # remove the token
            remove_token(serial)
Example #45
0
    def __init__(self,
                 msg=None,
                 data=None,
                 filename=None,
                 password=None,
                 vals=None,
                 file_obj=None,
                 validate_point=True,
                 _raw=None):
        self.verifying_key = None
        self.signing_key = None
        self.public_blob = None
        if file_obj is not None:
            _raw = self._from_private_key(file_obj, password)
        if filename is not None:
            _raw = self._from_private_key_file(filename, password)
        if _raw is not None:
            self._decode_key(_raw)
            return

        if (msg is None) and (data is not None):
            msg = Message(data)
        if vals is not None:
            self.signing_key, self.verifying_key = vals
            c_class = self.signing_key.curve.__class__
            self.ecdsa_curve = self._ECDSA_CURVES.get_by_curve_class(c_class)
        else:
            # Must set ecdsa_curve first; subroutines called herein may need to
            # spit out our get_name(), which relies on this.
            key_type = msg.get_text()
            # But this also means we need to hand it a real key/curve
            # identifier, so strip out any cert business. (NOTE: could push
            # that into _ECDSACurveSet.get_by_key_format_identifier(), but it
            # feels more correct to do it here?)
            suffix = '*****@*****.**'
            if key_type.endswith(suffix):
                key_type = key_type[:-len(suffix)]
            self.ecdsa_curve = self._ECDSA_CURVES.get_by_key_format_identifier(
                key_type)
            key_types = self._ECDSA_CURVES.get_key_format_identifier_list()
            cert_types = [
                '{}[email protected]'.format(x) for x in key_types
            ]
            self._check_type_and_load_cert(
                msg=msg,
                key_type=key_types,
                cert_type=cert_types,
            )
            curvename = msg.get_text()
            if curvename != self.ecdsa_curve.nist_name:
                raise SSHException(
                    "Can't handle curve of type {}".format(curvename))

            pointinfo = msg.get_binary()
            try:
                if hasattr(ec.EllipticCurvePublicKey, 'from_encoded_point'):
                    key = ec.EllipticCurvePublicKey.from_encoded_point(
                        self.ecdsa_curve.curve_class(), pointinfo)
                    self.verifying_key = key
                else:
                    numbers = ec.EllipticCurvePublicNumbers.from_encoded_point(
                        self.ecdsa_curve.curve_class(), pointinfo)
                    self.verifying_key = numbers.public_key(
                        backend=default_backend())
            except ValueError:
                raise SSHException("Invalid public key")
Example #46
0
def cert_pem_to_der(certificate):
    """Convert a PEM formatted cert to DER."""
    c = x509.load_pem_x509_certificate(certificate.encode(), default_backend())
    return c.public_bytes(serialization.Encoding.DER)
Example #47
0
 def add_from_der(self, crt_str):
     self.certificates.append(
         x509.load_der_x509_certificate(crt_str, default_backend()))
     status('Successfully added 1 certificate')
Example #48
0
def nc_scapy_pkt(pt_type, fields) -> bytes:
    """
    Generates NC scapy packets,

    :param pt_type: string in NC_PT_TYPES
    :param fields: list content depends on pt_type

    :return: scapy packet

    kep1 fields:
        fields[0]: eid, str
        fields[1]: ncname, str
        fields[2]: strategy, str
        fields[3]: wifi_mode, str

    kep4 fields:
        fields[0]: pri_key, bytes
        fields[1]: pub_key, tuple of bytes

    kep2 fields:
        fields[0]: kep4, bytes

    kep3 fields:
        fields[0]: pri_key, bytes
        fields[1]: pub_key, tuple of bytes

    eka fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int

    ewl fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int
        fields[3]: ip, list
        fields[4]: tcp_port, bytes

    eha fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int
        fields[3]: essid, bytes, 28 or DIRECT-
        fields[4]: password, bytes, 12 or 8
        fields[5]: tcp_port, bytes, 3

    esh fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int

    esh2 fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int

    pay fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int
        fields[3]: pt, bytes
        fields[4]: pid, bytes

    pay2 fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int
        fields[3]: pay_len, int
        fields[4]: pid, bytes

    iw fields:
        fields[0]: key, bytes
        fields[1]: iv, bytes
        fields[2]: count, int
        fields[3]: eid, str

    """
    validate_pt_type("nc_scapy_pkt", pt_type)

    rv = b''

    if pt_type == 'kep1':
        eid = fields[0]
        validate_str('nc_scapy_pkt kep1', eid)
        ncname = fields[1]
        validate_str('nc_scapy_pkt kep1', ncname)
        strategy = fields[2]
        validate_strategy('nc_scapy_pkt kep1', strategy)
        wifi_mode = fields[3]
        validate_wifi_mode('nc_scapy_pkt kep1', wifi_mode)

        # NOTE: use only latest version
        if strategy == 'P2P_STAR':
            if wifi_mode == 'hostapd':
                kep1_scapy = SCAPY_KEP1_STAR_HA_TEMPLATE
            elif wifi_mode == 'direct':
                kep1_scapy = SCAPY_KEP1_STAR_WD_TEMPLATE
        elif strategy == 'P2P_CLUSTER':
            kep1_scapy = SCAPY_KEP1_CLUS_TEMPLATE
        kep1_scapy.eid = eid
        kep1_scapy.ncname = ncname
        # NOTE: 4 depends on SCAPY_KEP1_TEMPLATE
        if len(ncname) != 4:
            delta = 4 - len(ncname)
            kep1_scapy.ncname_len = len(ncname)
            kep1_scapy.len1 -= delta
            kep1_scapy.len2 -= delta
            kep1_scapy.len3 -= delta
        # log.debug("nc_scapy_pkt kep1: {}".format(repr(kep1_scapy)))
        # log.debug("nc_scapy_pkt kep1_scapy.name: {}".format(kep1_scapy.name))

        rv = kep1_scapy

    elif pt_type == 'kep4':
        pri_key = fields[0]
        validate_pri_key('nc_scapy_pkt kep4', pri_key)
        pub_key = None
        pub_key = fields[1]

        if pub_key is not None:
            validate_pub_key('nc_scapy_pkt kep4', pub_key)
            # NOTE: not validating if it is in the curve
        else:
            pri_key_int = bytes_to_int(pri_key)
            pub_key_int = scalar_mult(pri_key_int, (EC_XG_INT, EC_YG_INT))
            pub_key = (int_to_bytes(pub_key_int[0]),
                       int_to_bytes(pub_key_int[1]))
            validate_point('nc_scapy_pkt kep4', pub_key)

        xD = pub_key[0]
        yD = pub_key[1]
        # NOTE: preprend \x00 if coordinate starts with 0b1
        if bin(xD[0]).startswith('0b1'):
            xD = b'\x00' + xD
        if bin(yD[0]).startswith('0b1'):
            yD = b'\x00' + yD

        kep4_scapy = SCAPY_KEP4_TEMPLATE
        # NOTE: 32 depends on the SCAPY_KEP4_TEMPLATE
        delta = 32 - len(xD) + 32 - len(yD)
        kep4_scapy.len1 -= delta
        kep4_scapy.len2 -= delta
        kep4_scapy.len3 -= delta
        kep4_scapy.len4 -= delta
        kep4_scapy.xD = xD
        kep4_scapy.xD_len = len(xD)
        kep4_scapy.yD = yD
        kep4_scapy.yD_len = len(yD)
        # log.debug("nc_scapy_pkt kep4_hex: {}".format(raw(kep4_scapy).hex()))

        rv = kep4_scapy

    # NOTE: so far passing constant kdf1 and kdf2
    elif pt_type == 'kep2':
        kep4 = fields[0]
        validate_bytes('nc_scapy_pkt kep2', kep4)

        kep2_scapy = SCAPY_KEP2_TEMPLATE

        kep0 = Hash(SHA512(), backend=default_backend())
        kep0.update(kep4[4:])
        kep2_kdf2 = kep0.finalize()

        kep2_scapy.kdf2 = kep2_kdf2

        rv = kep2_scapy

    elif pt_type == 'kep3':
        pri_key = fields[0]
        validate_pri_key('nc_scapy_pkt kep3', pri_key)
        pub_key = None
        pub_key = fields[1]

        # NOTE: if fields[1] contains a pub_key
        if pub_key is not None:
            validate_pub_key('nc_scapy_pkt kep3', pub_key)
            # NOTE: not validating if it is in the curve
        else:
            pri_key_int = bytes_to_int(pri_key)
            pub_key_int = scalar_mult(pri_key_int, (EC_XG_INT, EC_YG_INT))
            pub_key = (int_to_bytes(pub_key_int[0]),
                       int_to_bytes(pub_key_int[1]))
            validate_point('nc_scapy_pkt kep3', pub_key)

        xA = pub_key[0]
        yA = pub_key[1]
        # NOTE: preprend \x00 if coordinate starts with 0b1
        if bin(xA[0]).startswith('0b1'):
            xA = b'\x00' + xA
        if bin(yA[0]).startswith('0b1'):
            yA = b'\x00' + yA

        # NOTE: kdf field is kept constant so far
        kep3_scapy = SCAPY_KEP3_TEMPLATE
        # NOTE: 32 depends on the SCAPY_KEP3_TEMPLATE
        delta = 32 - len(xA) + 32 - len(yA)
        kep3_scapy.len1 -= delta
        kep3_scapy.len2 -= delta
        kep3_scapy.len3 -= delta
        kep3_scapy.len4 -= delta
        kep3_scapy.xA = xA
        kep3_scapy.xA_len = len(xA)
        kep3_scapy.yA = yA
        kep3_scapy.yA_len = len(yA)
        # log.debug("nc_scapy_pkt kep3_hex: {}".format(raw(kep3_scapy).hex()))

        rv = kep3_scapy

    elif pt_type == 'eka':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt eka", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt eka", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt eka", count)

        pt_scapy = SCAPY_KA_TEMPLATE
        pt_scapy.count = count
        pt = raw(pt_scapy)
        # log.debug("nc_scapy_pkt eka pt_hex: {} {}, count {}".format(pt.hex(),
        #     len(pt.hex()), count))
        ct = nc_encrypt(key, pt, iv)[2]
        mac = nc_mac(key, ct, iv, pt_type)[2]

        eka_scapy = SCAPY_EKA_TEMPLATE
        eka_scapy.iv = iv
        eka_scapy.ct = ct
        eka_scapy.mac = mac

        rv = eka_scapy

    elif pt_type == 'ewl':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt ewl", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt ewl", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt ewl", count)
        ip = fields[3]
        validate_ip("nc_scapy_pkt ewl", ip)

        wl_scapy = SCAPY_WL_TEMPLATE
        wl_scapy.count = count
        wl_scapy.ip = ip
        if fields[4] == None:
            # NOTE: use the tcp_port from the template
            pass
        else:
            tcp_port = fields[4]
            validate_tcp_port("nc_scapy_pkt ewl", tcp_port)
            wl_scapy.tcp_port = tcp_port
        pt = raw(wl_scapy)
        ct = nc_encrypt(key, pt, iv)[2]
        mac = nc_mac(key, ct, iv, pt_type)[2]

        # NOTE: similar to eka_scapy
        ewl_scapy = SCAPY_EWL_TEMPLATE
        ewl_scapy.iv = iv
        ewl_scapy.ct = ct
        ewl_scapy.mac = mac

        rv = ewl_scapy

    elif pt_type == 'eha':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt eha", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt eha", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt eha", count)
        essid = fields[3]
        validate_essid("nc_scapy_pkt eha", essid)
        password = fields[4]
        validate_password("nc_scapy_pkt eha", password)

        ha_scapy = SCAPY_HA_TEMPLATE
        ha_scapy.count = count
        ha_scapy.essid = essid
        ha_scapy.password = password
        if fields[5] == None:
            # NOTE: use the tcp_port from the template
            pass
        else:
            tcp_port = fields[5]
            validate_tcp_port("nc_scapy_pkt eha", tcp_port)
            ha_scapy.tcp_port = tcp_port
        pt = raw(ha_scapy)
        ct = nc_encrypt(key, pt, iv)[2]
        mac = nc_mac(key, ct, iv, pt_type)[2]

        # NOTE: similar to eka_scapy
        eha_scapy = SCAPY_EHA_TEMPLATE
        eha_scapy.iv = iv
        eha_scapy.ct = ct
        eha_scapy.mac = mac

        rv = eha_scapy

    elif pt_type == 'esh':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt esh", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt esh", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt esh", count)

        sh_scapy = SCAPY_SH_TEMPLATE
        sh_scapy.count = count
        pt = raw(sh_scapy)
        ct = nc_encrypt(key, pt, iv)[2]
        mac = nc_mac(key, ct, iv, pt_type)[2]

        esh_scapy = SCAPY_EKA_TEMPLATE
        esh_scapy.iv = iv
        esh_scapy.ct = ct
        esh_scapy.mac = mac

        rv = esh_scapy

    elif pt_type == 'esh2':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt esh2", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt esh2", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt esh2", count)

        sh2_scapy = SCAPY_SH2_TEMPLATE
        sh2_scapy.count = count
        pt = raw(sh2_scapy)
        ct = nc_encrypt(key, pt, iv)[2]
        mac = nc_mac(key, ct, iv, pt_type)[2]

        esh2_scapy = SCAPY_EKA_TEMPLATE
        esh2_scapy.iv = iv
        esh2_scapy.ct = ct
        esh2_scapy.mac = mac

        rv = esh2_scapy

    elif pt_type == 'pay':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt pay", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt pay", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt pay", count)
        pay = fields[3]
        validate_bytes("nc_scapy_pkt pay", pay)
        # pid = fields[4]
        # validate_bytes("nc_scapy_pkt pay", pid)

        # NOTE: uses Pt class
        pt_scapy = SCAPY_PT_TEMPLATE
        # NOTE: 4 depends on SCAPY_PT_TEMPLATE
        if len(pay) != 4:
            delta = 4 - len(pay)
            pt_scapy.len1 -= delta
            pt_scapy.len2 -= delta
            pt_scapy.len3 -= delta
            pt_scapy.pt_len = len(pay)
            pt_scapy.len4 -= delta
            pt_scapy.pay_len = len(pay)
        pt_scapy.pay = pay
        pt_scapy.count = count
        # log.debug("nc_scapy_pkt pt: {}".format(repr(pt_scapy)))

        pt = raw(pt_scapy)
        log.debug("nc_scapy_pkt pt_hex: {}".format(pt.hex()))
        ct = nc_encrypt(key, pt, iv)[2]
        mac = nc_mac(key, ct, iv, pt_type)[2]

        # NOTE: len fields should not be affected by len(Pt)
        pay_scapy = SCAPY_PAY_TEMPLATE
        pay_scapy.iv = iv
        pay_scapy.ct = ct
        pay_scapy.mac = mac

        rv = pay_scapy

    elif pt_type == 'pay2':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt pay2", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt pay2", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt pay2", count)
        pay_len = fields[3]  # this is the len of Pt (not Pt2)
        validate_int("nc_scapy_pkt pay2", pay_len)
        # pid = fields[4]
        # validate_bytes("nc_scapy_pkt pay2", pid)

        # NOTE: uses Pt2 class
        pt2_scapy = SCAPY_PT2_TEMPLATE
        if pay_len != 4:
            delta = 4 - pay_len
            pt2_scapy.pt_len = pay_len
            pt2_scapy.pt_len2 = pay_len
        pt2_scapy.count = count
        # log.debug("nc_scapy_pkt pt2: {}".format(repr(pt2_scapy)))

        pt = raw(pt2_scapy)
        log.debug("nc_scapy_pkt pt2_hex: {}".format(pt.hex()))
        # log.debug("nc_scapy_pkt pay pt_hex: {} {}, count {}".format(pt.hex(),
        #     len(pt.hex()), count))
        ct = nc_encrypt(key, pt, iv)[2]
        mac = nc_mac(key, ct, iv, pt_type)[2]

        pay2_scapy = SCAPY_PAY2_TEMPLATE
        pay2_scapy.iv = iv
        pay2_scapy.ct = ct
        pay2_scapy.mac = mac

        rv = pay2_scapy

    # NOTE: not encrypted, key and iv not used
    elif pt_type == 'iw':
        key = fields[0]
        validate_aes256_key("nc_scapy_pkt iw", key)
        iv = fields[1]
        validate_iv("nc_scapy_pkt iw", iv)
        count = fields[2]
        validate_int("nc_scapy_pkt iw", count)
        eid = eid[2]
        validate_str("nc_scapy_pkt iw", eid)

        iw_scapy = SCAPY_IW_TEMPLATE
        iw_scapy.count = count
        iw_scapy.eid = eid
        pt = raw(iw_scapy)
        # log.debug("nc_scapy_pkt iw pt_hex: {} {}, count {}".format(pt.hex(),
        #     len(pt.hex()), count))

        rv = iw_scapy

    else:
        log.error('nc_scapy_pkt: pt_type {} not managed.'.format(pt_type))

    return rv
Example #49
0
def get_backend():
    from cryptography.hazmat.backends import default_backend
    return default_backend()
Example #50
0
    hexstr = binascii.hexlify(content).decode("UTF-8")
    hexstr = hexstr.upper()
    array = ["0x" + hexstr[i:i + 2] + "" for i in range(0, len(hexstr), 2)]
    array = make_sublist_group(array, 10)
    
    return sum(len(a) for a in array ), "\n".join([", ".join(e) + ", " for e in array])


#Creating a Certificate


with open(sys.argv[1], "rb") as keyfile:
     private_key = serialization.load_pem_private_key(
        keyfile.read(),
        password=None,
        backend=default_backend()
    )
    
key_der = private_key.private_bytes(
        serialization.Encoding.DER,
        serialization.PrivateFormat.TraditionalOpenSSL,
        serialization.NoEncryption()
    )
key_length , keyArray=do_convension(key_der)

keyHeaderTemplate=Template("""
/*GENERATED FILE*/

#ifndef _KEY_TEST_H_
#define _KEY_TEST_H_
def getCertificateSignature(certificate_data):

    cert = crypto.x509.load_pem_x509_certificate(certificate_data,
                                                 default_backend())
    return cert.signature
Example #52
0
    async def start_client(
        self,
        target_node: PeerInfo,
        on_connect: Callable = None,
        auth: bool = False,
        is_feeler: bool = False,
    ) -> bool:
        """
        Tries to connect to the target node, adding one connection into the pipeline, if successful.
        An on connect method can also be specified, and this will be saved into the instance variables.
        """
        if self.is_duplicate_or_self_connection(target_node):
            return False

        if target_node.host in self.banned_peers and time.time() < self.banned_peers[target_node.host]:
            self.log.warning(f"Peer {target_node.host} is still banned, not connecting to it")
            return False

        if auth:
            ssl_context = ssl_context_for_client(
                self.ca_private_crt_path, self.ca_private_key_path, self._private_cert_path, self._private_key_path
            )
        else:
            ssl_context = ssl_context_for_client(
                self.chia_ca_crt_path, self.chia_ca_key_path, self.p2p_crt_path, self.p2p_key_path
            )
        session = None
        connection: Optional[WSChiaConnection] = None
        try:
            timeout = ClientTimeout(total=10)
            session = ClientSession(timeout=timeout)

            try:
                if type(ip_address(target_node.host)) is IPv6Address:
                    target_node = PeerInfo(f"[{target_node.host}]", target_node.port)
            except ValueError:
                pass

            url = f"wss://{target_node.host}:{target_node.port}/ws"
            self.log.debug(f"Connecting: {url}, Peer info: {target_node}")
            try:
                ws = await session.ws_connect(
                    url, autoclose=True, autoping=True, heartbeat=60, ssl=ssl_context, max_msg_size=50 * 1024 * 1024
                )
            except ServerDisconnectedError:
                self.log.debug(f"Server disconnected error connecting to {url}. Perhaps we are banned by the peer.")
                await session.close()
                return False
            except asyncio.TimeoutError:
                self.log.debug(f"Timeout error connecting to {url}")
                await session.close()
                return False
            if ws is not None:
                assert ws._response.connection is not None and ws._response.connection.transport is not None
                transport = ws._response.connection.transport  # type: ignore
                cert_bytes = transport._ssl_protocol._extra["ssl_object"].getpeercert(True)  # type: ignore
                der_cert = x509.load_der_x509_certificate(cert_bytes, default_backend())
                peer_id = bytes32(der_cert.fingerprint(hashes.SHA256()))
                if peer_id == self.node_id:
                    raise RuntimeError(f"Trying to connect to a peer ({target_node}) with the same peer_id: {peer_id}")

                connection = WSChiaConnection(
                    self._local_type,
                    ws,
                    self._port,
                    self.log,
                    True,
                    False,
                    target_node.host,
                    self.incoming_messages,
                    self.connection_closed,
                    peer_id,
                    self._inbound_rate_limit_percent,
                    self._outbound_rate_limit_percent,
                    session=session,
                )
                handshake = await connection.perform_handshake(
                    self._network_id,
                    protocol_version,
                    self._port,
                    self._local_type,
                )
                assert handshake is True
                await self.connection_added(connection, on_connect)
                connection_type_str = ""
                if connection.connection_type is not None:
                    connection_type_str = connection.connection_type.name.lower()
                self.log.info(f"Connected with {connection_type_str} {target_node}")
                if is_feeler:
                    asyncio.create_task(connection.close())
                return True
            else:
                await session.close()
                return False
        except client_exceptions.ClientConnectorError as e:
            self.log.info(f"{e}")
        except ProtocolError as e:
            if connection is not None:
                await connection.close(self.invalid_protocol_ban_seconds, WSCloseCode.PROTOCOL_ERROR, e.code)
            if e.code == Err.INVALID_HANDSHAKE:
                self.log.warning(f"Invalid handshake with peer {target_node}. Maybe the peer is running old software.")
            elif e.code == Err.INCOMPATIBLE_NETWORK_ID:
                self.log.warning("Incompatible network ID. Maybe the peer is on another network")
            elif e.code == Err.SELF_CONNECTION:
                pass
            else:
                error_stack = traceback.format_exc()
                self.log.error(f"Exception {e}, exception Stack: {error_stack}")
        except Exception as e:
            if connection is not None:
                await connection.close(self.invalid_protocol_ban_seconds, WSCloseCode.PROTOCOL_ERROR, Err.UNKNOWN)
            error_stack = traceback.format_exc()
            self.log.error(f"Exception {e}, exception Stack: {error_stack}")

        if session is not None:
            await session.close()

        return False
Example #53
0
    def calc_hmac(self, plainbytes, mac):
        h = hmac.HMAC(mac, hashes.SHA256(), backend=default_backend())
        h.update(plainbytes)
        hmac_ = h.finalize().hex()
        return hmac_


#sec = Security()
#secret = sec.updateEncryptor("3asdasdx")
#print("recovered", sec.updateDecryptor(secret))

with open("my_key.pem", "rb") as private_key_file_object:
    my_private_pem = private_key_file_object.read()
    my_private_key = serialization.load_pem_private_key(
        my_private_pem, backend=default_backend(), password=None)

with open("my_key_pub.pem", "rb") as public_key_file_object:
    my_public_pem = public_key_file_object.read()
    my_public_key = serialization.load_pem_public_key(
        my_public_pem, backend=default_backend())

with open("server_key.pem", "rb") as private_key_file_object:
    server_private_pem = private_key_file_object.read()
    server_private_key = serialization.load_pem_private_key(
        server_private_pem, backend=default_backend(), password=None)

with open("server_key_pub.pem", "rb") as public_key_file_object:
    server_public_pem = public_key_file_object.read()
    server_public_key = serialization.load_pem_public_key(
        server_public_pem, backend=default_backend())
Example #54
0
def register(config, account_storage, tos_cb=None):
    """Register new account with an ACME CA.

    This function takes care of generating fresh private key,
    registering the account, optionally accepting CA Terms of Service
    and finally saving the account. It should be called prior to
    initialization of `Client`, unless account has already been created.

    :param .IConfig config: Client configuration.

    :param .AccountStorage account_storage: Account storage where newly
        registered account will be saved to. Save happens only after TOS
        acceptance step, so any account private keys or
        `.RegistrationResource` will not be persisted if `tos_cb`
        returns ``False``.

    :param tos_cb: If ACME CA requires the user to accept a Terms of
        Service before registering account, client action is
        necessary. For example, a CLI tool would prompt the user
        acceptance. `tos_cb` must be a callable that should accept
        `.RegistrationResource` and return a `bool`: ``True`` iff the
        Terms of Service present in the contained
        `.Registration.terms_of_service` is accepted by the client, and
        ``False`` otherwise. ``tos_cb`` will be called only if the
        client acction is necessary, i.e. when ``terms_of_service is not
        None``. This argument is optional, if not supplied it will
        default to automatic acceptance!

    :raises letsencrypt.errors.Error: In case of any client problems, in
        particular registration failure, or unaccepted Terms of Service.
    :raises acme.errors.Error: In case of any protocol problems.

    :returns: Newly registered and saved account, as well as protocol
        API handle (should be used in `Client` initialization).
    :rtype: `tuple` of `.Account` and `acme.client.Client`

    """
    # Log non-standard actions, potentially wrong API calls
    if account_storage.find_all():
        logger.info("There are already existing accounts for %s", config.server)
    if config.email is None:
        if not config.register_unsafely_without_email:
            msg = ("No email was provided and "
                   "--register-unsafely-without-email was not present.")
            logger.warn(msg)
            raise errors.Error(msg)
        if not config.dry_run:
            logger.warn("Registering without email!")

    # Each new registration shall use a fresh new key
    key = jose.JWKRSA(key=jose.ComparableRSAKey(
        rsa.generate_private_key(
            public_exponent=65537,
            key_size=config.rsa_key_size,
            backend=default_backend())))
    acme = acme_from_config_key(config, key)
    # TODO: add phone?
    regr = perform_registration(acme, config)

    if regr.terms_of_service is not None:
        if tos_cb is not None and not tos_cb(regr):
            raise errors.Error(
                "Registration cannot proceed without accepting "
                "Terms of Service.")
        regr = acme.agree_to_tos(regr)

    acc = account.Account(regr, key)
    account.report_new_account(acc, config)
    account_storage.save(acc)

    return acc, acme
Example #55
0
def read_private(filename="private_noshare.pem"):
    with open(filename, "rb") as key_file:
        private_key = serialization.load_pem_private_key(
            key_file.read(), password=None, backend=default_backend())
    return private_key
Example #56
0
 def calc_hmac(self, plainbytes, mac):
     h = hmac.HMAC(mac, hashes.SHA256(), backend=default_backend())
     h.update(plainbytes)
     hmac_ = h.finalize().hex()
     return hmac_
Example #57
0
def decode_message(b64msg):
    global _crypt_keys
    global _public_keys
    global _ca_file

    # get the message
    try:
        msgstr = base64.b64decode(b64msg).decode('utf-8', 'ignore')
        iam_message = json.loads(msgstr)
    except json.decoder.JSONDecodeError as e:
        logging.info('Not an iam message: invalid json')
        raise MessageException('Not an iam message: invalid json', MessageException.not_iam_message)

    if 'header' not in iam_message:
        logging.info('Not an iam message: no header')
        raise MessageException('Not an iam message: no header', MessageException.not_iam_message)
    iamHeader = iam_message['header']

    try:
        # check the version
        if iamHeader[u'version'] != 'UWIT-2':
            logging.error('unknown version: ' + iamHeader[u'version'])
            raise MessageException('Unknown message version: ' + iamHeader[u'version'], MessageException.bad_version)

        # fetch the signing cert if it's not cached
        certurl = iamHeader[u'signingCertUrl']
        if certurl not in _public_keys:
            logging.info('Fetching signing cert: ' + certurl)
            pem = ''

            if certurl.startswith('file:'):
                with open(certurl[5:], 'r') as f:
                    pem = f.read()

            elif certurl.startswith('http'):
                if _ca_file is not None:
                    http = urllib3.PoolManager(
                        cert_reqs='CERT_REQUIRED',  # Force certificate check.
                        ca_certs=_ca_file,
                    )
                else:
                    http = urllib3.PoolManager()
                certdoc = http.request('GET', certurl)
                if certdoc.status != 200:
                    logger.error('sws cert get failed: ' + certdoc.status)
                    raise SigningCertException('Signers public key not found, url=%s,  status=%d' % (certurl, certdoc.status))
                logger.debug('got it')
                pem = certdoc.data
            else:
                raise SigningCertException('Invalid signers public key: ' + certurl)

            crt = x509.load_pem_x509_certificate(pem.encode('utf-8', 'ignore'), default_backend())
            key = crt.public_key()
            _public_keys[certurl] = key

        enctxt64 = iam_message[u'body']
        # print (enctxt64)

        # check the signature

        sigmsg = _build_sig_msg(iamHeader, enctxt64)
        pre = hashlib.sha256(sigmsg).digest()
        # print('dec sig = ' + iamHeader[u'signature'])
        sig = base64.b64decode(iamHeader[u'signature'].encode('utf-8', 'ignore'))
        pubkey = _public_keys[certurl]
        pubkey.verify(sig, sigmsg, a_padding.PSS(mgf=a_padding.MGF1(hashes.SHA256()), salt_length=32), hashes.SHA256())

        # decrypt the message
        if 'keyId' in iamHeader:
            iv64 = iamHeader[u'iv']
            iv = base64.b64decode(iv64.encode('utf-8', 'ignore'))
            keyid = iamHeader[u'keyId']
            if keyid not in _crypt_keys:
                logger.error('key ' + keyid + ' not found')
                raise CryptKeyException('Decryption key not found: ' + keyid)
            key = _crypt_keys[keyid]

            enctxt = base64.b64decode(enctxt64.encode('utf-8', 'ignore'))
            cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
            dec = cipher.decryptor()
            ptxt = dec.update(enctxt) + dec.finalize()

            unpadder = padding.PKCS7(128).unpadder()
            txt = unpadder.update(ptxt) + unpadder.finalize()
        else:
            txt = base64.b64decode(enctxt64.encode('utf-8', 'ignore'))

        txt = txt.decode('utf-8', 'ignore')

        iam_message[u'body'] = txt
        # context is b64 encoded
        try:
            iamHeader[u'messageContext'] = base64.b64decode(iamHeader[u'messageContext'].encode('utf-8', 'ignore')).decode('utf-8', 'ignore')
        except TypeError:
            logger.info('context not base64')
            iamHeader[u'messageContext'] = None
    except InvalidSignature as e:
        logger.error('signature verify fails')
        raise SignatureVerifyException(str(e))

    except KeyError as e:
        if 'AlarmName' in iam_message:
            logger.debug('alarm: ' + iam_message['AlarmName'])
            return iam_message

        logger.error('Unknown message key: ')
        raise MessageException('Message key: ' + str(e))

    return iam_message
Example #58
0
    parser.add_argument("--host", type=str, default="::")
    parser.add_argument("--port", type=int, default=4433)
    parser.add_argument("--private-key", type=str, required=True)
    parser.add_argument("--secrets-log-file", type=str)
    parser.add_argument("--stateless-retry", action="store_true")
    parser.add_argument("--verbose", "-v", action="store_true")
    args = parser.parse_args()

    logging.basicConfig(
        format="%(asctime)s %(levelname)s %(name)s %(message)s",
        level=logging.DEBUG if args.verbose else logging.INFO,
    )

    with open(args.certificate, "rb") as fp:
        certificate = x509.load_pem_x509_certificate(
            fp.read(), backend=default_backend()
        )
    with open(args.private_key, "rb") as fp:
        private_key = serialization.load_pem_private_key(
            fp.read(), password=None, backend=default_backend()
        )

    if args.secrets_log_file:
        secrets_log_file = open(args.secrets_log_file, "a")
    else:
        secrets_log_file = None

    # session tickets
    ticket_store = SessionTicketStore()

    loop = asyncio.get_event_loop()
Example #59
0
def encode_message(msg, header, cryptid, signid):

    iamHeader = {}
    iamHeader['version'] = 'UWIT-2'

    iamHeader['contentType'] = _if_simple(header['contentType'])
    iamHeader['messageType'] = _if_simple(header['messageType'])
    iamHeader['sender'] = _if_simple(header['sender'])
    iamHeader['messageId'] = str(uuid.uuid4())
    iamHeader['messageContext'] = base64.b64encode(header['messageContext'].encode('utf-8', 'ignore')).decode('utf-8', 'ignore')

    iamHeader['timestamp'] = datetime.datetime.utcnow().isoformat()
    if signid not in _private_keys:
        raise SigningCertException('Signing key not found: ' + signid)
    iamHeader['signingCertUrl'] = _private_keys[signid]['url']

    if cryptid is not None:
        if cryptid not in _crypt_keys:
            raise CryptKeyException('Encryption key not found: ' + cryptid)
        iamHeader['keyId'] = cryptid
        iv = os.urandom(16)
        iamHeader['iv'] = base64.b64encode(iv).decode('utf-8', 'ignore')
        padder = padding.PKCS7(128).padder()
        pmsg = padder.update(msg.encode('utf-8', 'ignore')) + padder.finalize()
        key = _crypt_keys[cryptid]
        cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
        enc = cipher.encryptor()
        txt = enc.update(pmsg) + enc.finalize()
        enctxt64 = base64.b64encode(txt).decode('utf-8', 'ignore')
        # print (enctxt64)
    else:
        enctxt64 = base64.b64encode(msg.encode('utf-8', 'ignore')).decode('utf-8', 'ignore')

    # gen the signature
    sigmsg = _build_sig_msg(iamHeader, enctxt64)
    # print ('sigmsg:' + sigmsg.decode('utf-8'))

    key = _private_keys[signid]['key']
    pre = hashlib.sha256(sigmsg).digest()

    # some advise the use of 'PSS.MAX_LENGTH' for the salt length, but
    # I don't see how that works with other languages

    sig = key.sign(sigmsg, a_padding.PSS(mgf=a_padding.MGF1(hashes.SHA256()), salt_length=32), hashes.SHA256())
    sig64 = base64.b64encode(sig).decode('utf-8', 'ignore')
    # print ('enc sig64 = ' + sig64)
    iamHeader['signature'] = sig64

    # debugging stuff
    # with open('sigmsg', 'w') as f:
    #    f.write(sigmsg.decode('utf-8'))
    # with open('sigsig', 'wb') as f:
    #    f.write(sig)

    body = {}
    body['Message'] = enctxt64

    iamMessage = {}
    iamMessage['header'] = iamHeader
    iamMessage['body'] = enctxt64

    m64 = base64.b64encode(json.dumps(iamMessage).encode('utf-8', 'ignore')).decode('utf-8', 'ignore')
    return m64
Example #60
0
def read_public(filename="public_shared.pem"):
    with open("public_shared.pem", "rb") as key_file:
        public_key = serialization.load_pem_public_key(
            key_file.read(), backend=default_backend())
    return public_key