diff --git a/Makefile b/Makefile index f3c38d3f5..73024fb4e 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ install: helm install connaisseur helm --atomic --create-namespace --namespace $(NAMESPACE) dev-install: - helm install --set kubernetes.deployment.replicasCount=1,kubernetes.deployment.imagePullPolicy=Never connaisseur helm --atomic --create-namespace --namespace $(NAMESPACE) + helm install --set kubernetes.deployment.replicasCount=1,kubernetes.deployment.imagePullPolicy=Never,application.logLevel=DEBUG connaisseur helm --atomic --create-namespace --namespace $(NAMESPACE) uninstall: helm uninstall connaisseur -n $(NAMESPACE) diff --git a/connaisseur/trust_root.py b/connaisseur/trust_root.py index e94583c8e..329d8a442 100644 --- a/connaisseur/trust_root.py +++ b/connaisseur/trust_root.py @@ -76,11 +76,17 @@ class ECDSAKey(TrustRootInterface): def __str__(self) -> str: return base64.b64encode(self.value.to_der()).decode("utf-8") + def pem(self): + return self.value.to_pem() + class RSAKey(TrustRootInterface): def __str__(self) -> str: return base64.b64encode(self.value.save_pkcs1("DER")).decode("utf-8") + def pem(self): + return self.value.save_pkcs1("PEM") + class KMSKey(TrustRootInterface): pass diff --git a/connaisseur/validators/cosign/cosign_validator.py b/connaisseur/validators/cosign/cosign_validator.py index 73b381559..14004860a 100644 --- a/connaisseur/validators/cosign/cosign_validator.py +++ b/connaisseur/validators/cosign/cosign_validator.py @@ -16,7 +16,7 @@ WrongKeyError, ) from connaisseur.image import Image -from connaisseur.trust_root import ECDSAKey, KMSKey, TrustRoot +from connaisseur.trust_root import ECDSAKey, KMSKey, RSAKey, TrustRoot from connaisseur.util import safe_path_func # nosec from connaisseur.validators.interface import ValidatorInterface @@ -213,7 +213,11 @@ async def __get_cosign_validated_digests(self, image: str, values: dict): image=str(image), trust_root=values["name"], ) - elif "Error: no matching signatures:\n\nmain.go:" in stderr: + elif ( + "Error: no matching signatures:\n\nmain.go:" in stderr + or "Error: no matching signatures:\ncrypto/rsa: verification error" + in stderr + ): msg = 'No trust data for image "{image}".' raise NotFoundException( message=msg, @@ -269,13 +273,13 @@ async def __validate_using_trust_root( # reminder when implementing Keyless validation: # ["--cert-email", self.value, b""] - if isinstance(trust_root, ECDSAKey): + if isinstance(trust_root, (ECDSAKey, RSAKey)): return await self.__invoke_cosign( image, { "option_kword": "--key", "inline_tr": "/dev/stdin", - "trust_root": trust_root.value.to_pem(), + "trust_root": trust_root.pem(), }, verify_tlog, ) diff --git a/tests/integration/cases.yaml b/tests/integration/cases.yaml index 253a61d15..e9641ae4a 100644 --- a/tests/integration/cases.yaml +++ b/tests/integration/cases.yaml @@ -89,6 +89,13 @@ test_cases: txt: Testing signed cosign image with tag and digest... type: deploy ref: securesystemsengineering/testimage:co-signed@sha256:c5327b291d702719a26c6cf8cc93f72e7902df46547106a9930feda2c002a4a7 + - id: crsa + txt: Testing signed cosign image, signed with RSA key + type: deploy + ref: securesystemsengineering/testimage:rsa-co-signed + namespace: default + expected_msg: pod/pod-crsa-${RAND} created + expected_result: null multi-cosigned: - id: mc-u txt: Testing multi-cosigned image `threshold` => undefined, not reached... diff --git a/tests/integration/update.yaml b/tests/integration/update.yaml index 153e69a4d..83b55a870 100644 --- a/tests/integration/update.yaml +++ b/tests/integration/update.yaml @@ -67,6 +67,20 @@ application: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqxgd/RqCdPnafQmlmX71eICGRBqu USHEjAv3FZCROHLYts11xR6Peu8ZEvMXOR46L7+z84DRFK6gnTInbIGFmg== -----END PUBLIC KEY----- + - name: rsa + type: cosign + trustRoots: + - name: default + key: | + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxmEXG8savZ/Q8IJB8dBT + YCKV/ECwkj8zBInilrWSipsKiBwGTugAgKHj7Nvo6pg91DTESpfnryL+UUwAyJ1C + irdUThCZa90vC9SlwYUhC/ftz/dwU8KaiVcWJHCbj4VLLCD7xVKPh65j4x65D8bL + ohbrpZFfboXgG/gJHYhU18q0nmGzuQyGWSxAYcsh8qVcaNa68TvZLqecq/AYvspI + qNIGWekU1BYXoUVt6kBx/fwEKtxESRbgsT1R8ha+q1HTGLMtj71LfWfX9d1bbNeq + 2+pXRO8Ut8km2lGEekRNXYb2C+sOX7uA1MSv+gm2JCoVzep69fGTHbqOwf4tm2Qh + AwIDAQAB + -----END PUBLIC KEY----- policy: - pattern: "*:*" validator: dockerhub-basics @@ -116,6 +130,10 @@ application: with: trustRoot: securesystemsengineering-official delegations: ["belitzphilipp", "starkteetje"] + - pattern: "docker.io/securesystemsengineering/testimage:rsa-*" + validator: rsa + with: + verifyInTransparencyLog: false features: detectionMode: false automaticChildApproval: true diff --git a/tests/test_trust_root.py b/tests/test_trust_root.py index a38444607..ad2378292 100644 --- a/tests/test_trust_root.py +++ b/tests/test_trust_root.py @@ -25,6 +25,10 @@ sample_ecdsa2 = "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEi2WD/E/UXF4+yoE5e4cjpJMNgQw\n8PAVALRX+8f8I8B+XneAtnOHDTI8L6wBeFRTzl6G4OmgDyCRYTb5MV3hog==\n-----END PUBLIC KEY-----" +ecdsa_bytes = b"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOXYta5TgdCwXTCnLU09W5T4M4r9f\nQQrqJuADP6U7g5r9ICgPSmZuRHP/1AYUfOQW3baveKsT969EfELKj1lfCA==\n-----END PUBLIC KEY-----\n" +# for some reason the public key differs from the read one :shrug: +rsa_bytes = b"-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAs5pC7R5OTSTUMJHUniPkrLfmGDAUxZtRlvIE+pGPCD6cUXH22adv\nkK87xwpupjxdVYuKTFnWHUIyFJwjI3vusievezcAr0E/xxyeo49tWog9kFoooK3q\nmXjpETC8OpvNROZ0K3qhlm9PZkGo3gSJ/B4rMU/d+jkCI8eiUPpdVQOczdBoD5nz\nQAF1mfmffWGsbKY+d8/l77Vset0GXExRzUtnglMhREyHNpDeQUg5OEn+kuGLlTzI\nxpIF+MlbzP3+xmNEzH2iafr0ae2g5kX2880priXpxG8GXW2ybZmPvchclnvFu4Zf\nZcM10FpgYJFvR/9iofFeAka9u5z6VZccmQIDAQAB\n-----END RSA PUBLIC KEY-----\n" + def cb(image, key_args): return key_args[:2] @@ -82,3 +86,17 @@ def test_keys(data, class_, exception): def test_str(key, out): k = trust_root.TrustRoot(key) assert str(k) == out + + +@pytest.mark.parametrize( + "key, out, exception", + [ + (sample_ecdsa, ecdsa_bytes, fix.no_exc()), + (sample_rsa, rsa_bytes, fix.no_exc()), + (sample_mail, b"", pytest.raises(AttributeError)), + ], +) +def test_pem(key, out, exception): + k = trust_root.TrustRoot(key) + with exception: + assert k.pem() == out