mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add tons of test cases
This commit is contained in:
@@ -543,3 +543,173 @@ Feature: External CA
|
||||
| {} | ["infisical.com", "localhost"] | Invalid CSR: dns_name SAN value 'localhost' is not in allowed values list |
|
||||
| {"COMMON_NAME": "example.com"} | ["infisical.com", "localhost"] | Invalid CSR: dns_name SAN value 'localhost' is not in allowed values list |
|
||||
|
||||
|
||||
Scenario Outline: Issue a certificate with algorithms disallowed by the template
|
||||
Given I create a Cloudflare connection as cloudflare
|
||||
Then I memorize cloudflare with jq ".appConnection.id" as app_conn_id
|
||||
Given I create a external ACME CA with the following config as ext_ca
|
||||
"""
|
||||
{
|
||||
"dnsProviderConfig": {
|
||||
"provider": "cloudflare",
|
||||
"hostedZoneId": "MOCK_ZONE_ID"
|
||||
},
|
||||
"directoryUrl": "{PEBBLE_URL}",
|
||||
"accountEmail": "fangpen@infisical.com",
|
||||
"dnsAppConnectionId": "{app_conn_id}",
|
||||
"eabKid": "",
|
||||
"eabHmacKey": ""
|
||||
}
|
||||
"""
|
||||
Then I memorize ext_ca with jq ".id" as ext_ca_id
|
||||
Given I create a certificate template with the following config as cert_template
|
||||
"""
|
||||
{
|
||||
"subject": [
|
||||
{
|
||||
"type": "common_name",
|
||||
"allowed": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"sans": [
|
||||
{
|
||||
"type": "dns_name",
|
||||
"allowed": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"keyUsages": {
|
||||
"required": [],
|
||||
"allowed": [
|
||||
"digital_signature",
|
||||
"key_encipherment",
|
||||
"non_repudiation",
|
||||
"data_encipherment",
|
||||
"key_agreement",
|
||||
"key_cert_sign",
|
||||
"crl_sign",
|
||||
"encipher_only",
|
||||
"decipher_only"
|
||||
]
|
||||
},
|
||||
"extendedKeyUsages": {
|
||||
"required": [],
|
||||
"allowed": [
|
||||
"client_auth",
|
||||
"server_auth",
|
||||
"code_signing",
|
||||
"email_protection",
|
||||
"ocsp_signing",
|
||||
"time_stamping"
|
||||
]
|
||||
},
|
||||
"algorithms": {
|
||||
"signature": [
|
||||
"<allowed_signature>"
|
||||
],
|
||||
"keyAlgorithm": [
|
||||
"<allowed_alg>"
|
||||
]
|
||||
},
|
||||
"validity": {
|
||||
"max": "365d"
|
||||
}
|
||||
}
|
||||
"""
|
||||
Then I memorize cert_template with jq ".certificateTemplate.id" as cert_template_id
|
||||
Given I create an ACME profile with ca {ext_ca_id} and template {cert_template_id} as "acme_profile"
|
||||
When I have an ACME client connecting to "{BASE_URL}/api/v1/cert-manager/acme/profiles/{acme_profile.id}/directory"
|
||||
Then I register a new ACME account with email fangpen@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account
|
||||
When I create certificate signing request as csr
|
||||
Then I add names to certificate signing request csr
|
||||
"""
|
||||
{}
|
||||
"""
|
||||
Then I add subject alternative name to certificate signing request csr
|
||||
"""
|
||||
[
|
||||
"localhost"
|
||||
]
|
||||
"""
|
||||
And I create a <key_type> private key pair as cert_key
|
||||
And I sign the certificate signing request csr with "<hash_type>" hash and private key cert_key and output it as csr_pem in PEM format
|
||||
And I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order
|
||||
And I pass all challenges with type http-01 for order in order
|
||||
Given I intercept outgoing requests
|
||||
"""
|
||||
[
|
||||
{
|
||||
"scope": "https://api.cloudflare.com:443",
|
||||
"method": "POST",
|
||||
"path": "/client/v4/zones/MOCK_ZONE_ID/dns_records",
|
||||
"status": 200,
|
||||
"response": {
|
||||
"result": {
|
||||
"id": "A2A6347F-88B5-442D-9798-95E408BC7701",
|
||||
"name": "Mock Account",
|
||||
"type": "standard",
|
||||
"settings": {
|
||||
"enforce_twofactor": false,
|
||||
"api_access_enabled": null,
|
||||
"access_approval_expiry": null,
|
||||
"abuse_contact_email": null,
|
||||
"user_groups_ui_beta": false
|
||||
},
|
||||
"legacy_flags": {
|
||||
"enterprise_zone_quota": {
|
||||
"maximum": 0,
|
||||
"current": 0,
|
||||
"available": 0
|
||||
}
|
||||
},
|
||||
"created_on": "2013-04-18T00:41:02.215243Z"
|
||||
},
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": []
|
||||
},
|
||||
"responseIsBinary": false
|
||||
},
|
||||
{
|
||||
"scope": "https://api.cloudflare.com:443",
|
||||
"method": "GET",
|
||||
"path": {
|
||||
"regex": "/client/v4/zones/[^/]+/dns_records\\?"
|
||||
},
|
||||
"status": 200,
|
||||
"response": {
|
||||
"result": [],
|
||||
"success": true,
|
||||
"errors": [],
|
||||
"messages": [],
|
||||
"result_info": {
|
||||
"page": 1,
|
||||
"per_page": 100,
|
||||
"count": 0,
|
||||
"total_count": 0,
|
||||
"total_pages": 1
|
||||
}
|
||||
},
|
||||
"responseIsBinary": false
|
||||
}
|
||||
]
|
||||
"""
|
||||
Then I poll and finalize the ACME order order as finalized_order
|
||||
And the value error.typ should be equal to "urn:ietf:params:acme:error:badCSR"
|
||||
And the value error.detail should be equal to "<err_detail>"
|
||||
|
||||
Examples:
|
||||
| allowed_alg | allowed_signature | key_type | hash_type | err_detail |
|
||||
| RSA-4096 | SHA512-RSA | RSA-2048 | SHA512 | Invalid CSR: Key algorithm 'RSA_2048' is not allowed by template policy |
|
||||
| RSA-4096 | SHA512-RSA | RSA-3072 | SHA512 | Invalid CSR: Key algorithm 'RSA_3072' is not allowed by template policy |
|
||||
| RSA-4096 | ECDSA-SHA512 | ECDSA-P256 | SHA512 | Invalid CSR: Key algorithm 'EC_prime256v1' is not allowed by template policy |
|
||||
| RSA-4096 | ECDSA-SHA512 | ECDSA-P384 | SHA512 | Invalid CSR: Key algorithm 'EC_secp384r1' is not allowed by template policy |
|
||||
| RSA-4096 | ECDSA-SHA512 | ECDSA-P521 | SHA512 | Invalid CSR: Key algorithm 'EC_secp521r1' is not allowed by template policy |
|
||||
| RSA-2048 | SHA512-RSA | RSA-2048 | SHA384 | Invalid CSR: Signature algorithm 'RSA-SHA384' is not allowed by template policy |
|
||||
| RSA-2048 | SHA512-RSA | RSA-2048 | SHA256 | Invalid CSR: Signature algorithm 'RSA-SHA256' is not allowed by template policy |
|
||||
| RSA-2048 | SHA512-RSA | RSA-2048 | SHA384 | Invalid CSR: Signature algorithm 'RSA-SHA256' is not allowed by template policy |
|
||||
| RSA-2048 | SHA512-RSA | RSA-2048 | SHA256 | Invalid CSR: Signature algorithm 'RSA-SHA256' is not allowed by template policy |
|
||||
| RSA-2048 | SHA512-RSA | RSA-4096 | SHA256 | Invalid CSR: Signature algorithm 'RSA-SHA256' is not allowed by template policy, Invalid CSR: Key algorithm 'RSA_2048' is not allowed by template policy |
|
||||
|
||||
@@ -20,6 +20,10 @@ from josepy.jwk import JWKRSA
|
||||
from josepy import json_util
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric.types import (
|
||||
CertificateIssuerPrivateKeyTypes,
|
||||
)
|
||||
from cryptography import x509
|
||||
from cryptography.x509.oid import NameOID
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
@@ -597,12 +601,57 @@ def step_impl(context: Context, csr_var: str):
|
||||
)
|
||||
|
||||
|
||||
@then("I create a RSA private key pair as {rsa_key_var}")
|
||||
def step_impl(context: Context, rsa_key_var: str):
|
||||
context.vars[rsa_key_var] = rsa.generate_private_key(
|
||||
# TODO: make them configurable if we need to
|
||||
public_exponent=65537,
|
||||
key_size=2048,
|
||||
def gen_private_key(key_type: str):
|
||||
if key_type == "RSA-2048" or key_type == "RSA":
|
||||
return rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=2048,
|
||||
)
|
||||
elif key_type == "RSA-3072":
|
||||
return rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=3072,
|
||||
)
|
||||
elif key_type == "RSA-4096":
|
||||
return rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=4096,
|
||||
)
|
||||
elif key_type == "ECDSA-P256":
|
||||
return ec.generate_private_key(curve=ec.SECP256R1())
|
||||
elif key_type == "ECDSA-P384":
|
||||
return ec.generate_private_key(curve=ec.SECP384R1())
|
||||
elif key_type == "ECDSA-P521":
|
||||
return ec.generate_private_key(curve=ec.SECP521R1())
|
||||
else:
|
||||
raise Exception(f"Unknown key type {key_type}")
|
||||
|
||||
|
||||
@then("I create a {key_type} private key pair as {rsa_key_var}")
|
||||
def step_impl(context: Context, key_type: str, rsa_key_var: str):
|
||||
context.vars[rsa_key_var] = gen_private_key(key_type)
|
||||
|
||||
|
||||
def sign_csr(
|
||||
pem: x509.CertificateSigningRequestBuilder,
|
||||
pk: CertificateIssuerPrivateKeyTypes,
|
||||
hash_type: str = "SHA256",
|
||||
):
|
||||
return pem.sign(pk, getattr(hashes, hash_type)()).public_bytes(
|
||||
serialization.Encoding.PEM
|
||||
)
|
||||
|
||||
|
||||
@then(
|
||||
'I sign the certificate signing request {csr_var} with "{hash_type}" hash and private key {pk_var} and output it as {pem_var} in PEM format'
|
||||
)
|
||||
def step_impl(
|
||||
context: Context, csr_var: str, hash_type: str, pk_var: str, pem_var: str
|
||||
):
|
||||
context.vars[pem_var] = sign_csr(
|
||||
pem=context.vars[csr_var],
|
||||
pk=context.vars[pk_var],
|
||||
hash_type=hash_type,
|
||||
)
|
||||
|
||||
|
||||
@@ -610,10 +659,9 @@ def step_impl(context: Context, rsa_key_var: str):
|
||||
"I sign the certificate signing request {csr_var} with private key {pk_var} and output it as {pem_var} in PEM format"
|
||||
)
|
||||
def step_impl(context: Context, csr_var: str, pk_var: str, pem_var: str):
|
||||
context.vars[pem_var] = (
|
||||
context.vars[csr_var]
|
||||
.sign(context.vars[pk_var], hashes.SHA256())
|
||||
.public_bytes(serialization.Encoding.PEM)
|
||||
context.vars[pem_var] = sign_csr(
|
||||
pem=context.vars[csr_var],
|
||||
pk=context.vars[pk_var],
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user