diff options
Diffstat (limited to 'tests/AttestationVerificationTest')
11 files changed, 894 insertions, 4 deletions
diff --git a/tests/AttestationVerificationTest/Android.bp b/tests/AttestationVerificationTest/Android.bp index a4741eedaac0..b98f8cb0c21d 100644 --- a/tests/AttestationVerificationTest/Android.bp +++ b/tests/AttestationVerificationTest/Android.bp @@ -40,5 +40,6 @@ android_test { "androidx.test.rules", "androidx.test.ext.junit", "platform-test-annotations", + "services.core", ], } diff --git a/tests/AttestationVerificationTest/AndroidManifest.xml b/tests/AttestationVerificationTest/AndroidManifest.xml index c42bde9dca3a..37321ad80b0f 100755 --- a/tests/AttestationVerificationTest/AndroidManifest.xml +++ b/tests/AttestationVerificationTest/AndroidManifest.xml @@ -24,6 +24,7 @@ <application> <uses-library android:name="android.test.runner"/> <activity android:name=".SystemAttestationVerificationTest$TestActivity" /> + <activity android:name=".PeerDeviceSystemAttestationVerificationTest$TestActivity" /> </application> <!-- self-instrumenting test package. --> diff --git a/tests/AttestationVerificationTest/assets/test_attestation_with_root_certs.pem b/tests/AttestationVerificationTest/assets/test_attestation_with_root_certs.pem new file mode 100644 index 000000000000..e29ff487806e --- /dev/null +++ b/tests/AttestationVerificationTest/assets/test_attestation_with_root_certs.pem @@ -0,0 +1,81 @@ +-----BEGIN CERTIFICATE----- +MIICkjCCAjmgAwIBAgIBATAKBggqhkjOPQQDAjA5MQwwCgYDVQQMDANURUUxKTAn +BgNVBAUTIDg2ZTQ0MjRhMjY2NDlhZDcyZWZhNWM0MWEwM2IyN2QxMCAXDTcwMDEw +MTAwMDAwMFoYDzIxMDYwMjA3MDYyODE1WjAfMR0wGwYDVQQDDBRBbmRyb2lkIEtl +eXN0b3JlIEtleTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIlTwcvhe+DLV45X +RCTO7HoN20Ib7IbCEhV5+YdMiYOp/0AdKk8oYvsri1XODeC4zcoPfHNdQGt/68i0 +ADbilJmjggFIMIIBRDAOBgNVHQ8BAf8EBAMCB4AwggEwBgorBgEEAdZ5AgERBIIB +IDCCARwCAQMKAQECAQQKAQEECXBsYXllcjQ1NgQAMFe/hT0IAgYBfvkgVei/hUVH +BEUwQzEdMBsEFmNvbS5nb29nbGUuYXR0ZXN0YXRpb24CAQExIgQgOqyVXRJUdAGY +/XVx8y/uRPiebqlyELt1EpqIz29h5tUwgaehCDEGAgECAgEDogMCAQOjBAICAQCl +CDEGAgEEAgEGqgMCAQG/g3cCBQC/hT4DAgEAv4VATDBKBCCEZx8qY8Ys0HC2TqPq +74eYPzh5L/agxD7Bn7zVBQHoNAEB/woBAAQguJwoDfWBjRaedzQ6TJPFJJKs+ytr ++8Vu2CSmqifFBHW/hUEFAgMB1MC/hUIFAgMDFdm/hU4GAgQBNIjJv4VPBgIEATSI +yTAKBggqhkjOPQQDAgNHADBEAiBdGxfMEx59k5+zo+hV3Q9kgjbGi0zU3WH355P5 +JZttBwIgY4FZsSreUJL8RY3JvfvD8BRw8GuXcB1OQ600hwaYYC4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB8zCCAXqgAwIBAgIRAOuuukN0OHbNQvKngECkewEwCgYIKoZIzj0EAwIwOTEM +MAoGA1UEDAwDVEVFMSkwJwYDVQQFEyA3MDkxMmRmNDYxMDRmYWFlOTQ3ODY0ZTU4 +MDRmMWY4ZDAeFw0yMDA5MjgyMDI3NTZaFw0zMDA5MjYyMDI3NTZaMDkxDDAKBgNV +BAwMA1RFRTEpMCcGA1UEBRMgODZlNDQyNGEyNjY0OWFkNzJlZmE1YzQxYTAzYjI3 +ZDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT3Mjl05ewv6G8zAR4fXJy2iadU +yK7rNvzlECy2+nhEieL8BFXDvo0tx5fYs8qr67j/KvluFBfp2r9s+ckWz3Kzo2Mw +YTAdBgNVHQ4EFgQUsVKBzAs1lMXAauQ3mGAJZJqK5tAwHwYDVR0jBBgwFoAUEsQA +i8d2oLULSi5Ix4BTGGbvUEkwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AgQwCgYIKoZIzj0EAwIDZwAwZAIwfFziBCwuM1thLUSUNI61Xx/vnDnNkSv/aX5D +yLjxbLlgnFSzIrc+6vf6h6L/+TjYAjAq6h9GKtMn4R0286MoqYqzp/rHn6JD2sqH +iM8KZ0oA+Ut242EcmGjAoNfGZGZGddQ= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDkzCCAXugAwIBAgIQNTAX5z3CBac6nD3hQiMDcDANBgkqhkiG9w0BAQsFADAb +MRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MB4XDTIwMDkyODIwMjUwMloXDTMw +MDkyNjIwMjUwMlowOTEMMAoGA1UEDAwDVEVFMSkwJwYDVQQFEyA3MDkxMmRmNDYx +MDRmYWFlOTQ3ODY0ZTU4MDRmMWY4ZDB2MBAGByqGSM49AgEGBSuBBAAiA2IABA/7 +xZFlFtTjdy2B3p7E+FsrBjyhBSqY4a9FywawXMJRSja3HAK36ruzJjWlEkD+D0vq +HI2joY39FHmWoZWwm2cq9gOleFGYOSCpMr4ib7xtq/6nefvKTP5rutxudF97t6Nj +MGEwHQYDVR0OBBYEFBLEAIvHdqC1C0ouSMeAUxhm71BJMB8GA1UdIwQYMBaAFDZh +4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgIEMA0GCSqGSIb3DQEBCwUAA4ICAQAaMONDQxJz3PRn9gHQW5KP+TIoBPJZyGa1 +QFuEBcMDTtIxBxEh5Pj3ivPBc76PrdYu5U47Ve5YYCPsTpUTj7dOxbzGSZjfjvHF +fNwy24g1Lah2iAdQRVErhWKBlpnQhBnnRrrNmTTmzhl8NvSExqAPP746dqwm1kQ7 +YesC5yoEAHpxamhlZpIKAjSxSZeHWace2qV00M8qWd/7lIpqttJjFFrhCjzR0dtr +oIIpC5EtmqIWdLeg6yZjJkX+Cjv4F8mRfBtwuNuxFsfALQ3D5l8WKw3iwPebmCy1 +kEby8Eoq88FxzXQp/XgAaljlrKXyuxptrc1noRuob4g42Oh6wetueYRSCtO6Bkym +0UMnld/kG77aeiHOMVVb86wrhNuAGir1vgDGOBsclITVyuu9ka0YVQjjDm3phTpd +O8JV16gbei2Phn+FfRV1MSDsZo/wu0i2KVzgs27bfJocMHXv+GzvwfefYgMJ/rYq +Bg27lpsWzmFEPv2cyhA5PwwbG8ceswa3RZE/2eS9o7STkz93jr/KsKLcMBY6cX2C +q4CBJByKFJtVANOVj+neFNxc2sQgeTT33yYNKbe4b5bm7Ki1FbrhFVckpzUGDnKs +gL+AxvALWOoryDGwNbJiW8PRiD3HHByiMvSEQ7e7BSc2KjbsaWbCfYZAMZJEhEsc +P1l8lcUVuA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFHDCCAwSgAwIBAgIJANUP8luj8tazMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV +BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTkxMTIyMjAzNzU4WhcNMzQxMTE4MjAz +NzU4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS +Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7 +tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj +nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq +C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ +oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O +JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg +sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi +igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M +RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E +aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um +AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud +IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBOMaBc8oumXb2voc7XCWnu +XKhBBK3e2KMGz39t7lA3XXRe2ZLLAkLM5y3J7tURkf5a1SutfdOyXAmeE6SRo83U +h6WszodmMkxK5GM4JGrnt4pBisu5igXEydaW7qq2CdC6DOGjG+mEkN8/TA6p3cno +L/sPyz6evdjLlSeJ8rFBH6xWyIZCbrcpYEJzXaUOEaxxXxgYz5/cTiVKN2M1G2ok +QBUIYSY6bjEL4aUN5cfo7ogP3UvliEo3Eo0YgwuzR2v0KR6C1cZqZJSTnghIC/vA +D32KdNQ+c3N+vl2OTsUVMC1GiWkngNx1OO1+kXW+YTnnTUOtOIswUP/Vqd5SYgAI +mMAfY8U9/iIgkQj6T2W6FsScy94IN9fFhE1UtzmLoBIuUFsVXJMTz+Jucth+IqoW +Fua9v1R93/k98p41pjtFX+H8DslVgfP097vju4KDlqN64xV1grw3ZLl4CiOe/A91 +oeLm2UHOq6wn3esB4r2EIQKb6jTVGu5sYCcdWpXr0AUVqcABPdgL+H7qJguBw09o +jm6xNIrw2OocrDKsudk/okr/AwqEyPKw9WnMlQgLIKw1rODG2NvU9oR3GVGdMkUB +ZutL8VuFkERQGt6vQ2OCw0sV47VMkuYbacK/xyZFiRcrPJPb41zgbQj9XAEyLKCH +ex0SdDrx+tWUDqG8At2JHA== +-----END CERTIFICATE----- diff --git a/tests/AttestationVerificationTest/assets/test_attestation_wrong_root_certs.pem b/tests/AttestationVerificationTest/assets/test_attestation_wrong_root_certs.pem new file mode 100644 index 000000000000..3d6410af042a --- /dev/null +++ b/tests/AttestationVerificationTest/assets/test_attestation_wrong_root_certs.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIGCDCCBHCgAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRkwFwYDVQQFExAyZGM1OGIyZDFhMjQx +MzI2MQwwCgYDVQQMDANURUUwIBcNNzAwMTAxMDAwMDAwWhgPMjEwNjAyMDcwNjI4MTVaMB8xHTAb +BgNVBAMMFEFuZHJvaWQgS2V5c3RvcmUgS2V5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEApNVcnyN40MANMbbo2nMGNq2NNysDSjfLm0W3i6wPKf0ffCYkhWM4dCmQKKf50uAZTBeTit4c +NwXeZn3qellMlOsIN3Qc384rfN/8cikrRvUAgibz0Jy7STykjwa7x6tKwqITxbO8HqAhKo8/BQXU +xzrOdIg5ciy+UM7Vgh7a7ogen0KL2iGgrsalb1ti7Vlzb6vIJ4WzIC3TGD2sCkoPahghwqFDZZCo +/FzaLoNY0jAUX2mL+kf8aUaoxz7xA9FTvgara+1pLBR1s4c8xPS2HdZipcVXWfey0wujv1VAKs4+ +tXjKlHkYBHBBceEjxUtEmrapSQEdpHPv7Xh9Uanq4QIDAQABo4ICwTCCAr0wDgYDVR0PAQH/BAQD +AgeAMIICqQYKKwYBBAHWeQIBEQSCApkwggKVAgEDCgEBAgEECgEBBANhYmMEADCCAc2/hT0IAgYB +ZOYGEYe/hUWCAbsEggG3MIIBszGCAYswDAQHYW5kcm9pZAIBHTAZBBRjb20uYW5kcm9pZC5rZXlj +aGFpbgIBHTAZBBRjb20uYW5kcm9pZC5zZXR0aW5ncwIBHTAZBBRjb20ucXRpLmRpYWdzZXJ2aWNl +cwIBHTAaBBVjb20uYW5kcm9pZC5keW5zeXN0ZW0CAR0wHQQYY29tLmFuZHJvaWQuaW5wdXRkZXZp +Y2VzAgEdMB8EGmNvbS5hbmRyb2lkLmxvY2FsdHJhbnNwb3J0AgEdMB8EGmNvbS5hbmRyb2lkLmxv +Y2F0aW9uLmZ1c2VkAgEdMB8EGmNvbS5hbmRyb2lkLnNlcnZlci50ZWxlY29tAgEdMCAEG2NvbS5h +bmRyb2lkLndhbGxwYXBlcmJhY2t1cAIBHTAhBBxjb20uZ29vZ2xlLlNTUmVzdGFydERldGVjdG9y +AgEdMCIEHWNvbS5nb29nbGUuYW5kcm9pZC5oaWRkZW5tZW51AgEBMCMEHmNvbS5hbmRyb2lkLnBy +b3ZpZGVycy5zZXR0aW5ncwIBHTEiBCAwGqPLCBE0UBxF8UIqvGbCQiT9Xe1f3I8X5pcXb9hmqjCB +rqEIMQYCAQICAQOiAwIBAaMEAgIIAKUFMQMCAQSmCDEGAgEDAgEFv4FIBQIDAQABv4N3AgUAv4U+ +AwIBAL+FQEwwSgQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQAKAQIEIHKNsSdP +HxzxVx3kOAsEilVKxKOA529TVQg1KQhKk3gBv4VBAwIBAL+FQgUCAwMUs7+FTgUCAwMUs7+FTwUC +AwMUszANBgkqhkiG9w0BAQsFAAOCAYEAJMIuzdNUdfrE6sIdmsnMn/scSG2odbphj8FkX9JGdF2S +OT599HuDY9qhvkru2Dza4sLKK3f4ViBhuR9lpfeprKvstxbtBO7jkLYfVn0ZRzHRHVEyiW5IVKh+ +qOXVJ9S1lMShOTlsaYJytLKIlcrRAZBEXZiNbzTuVh1CH6X9Ni1dog14snm+lcOeORdL9fht2CHa +u/caRnpWiZbjoAoJp0O89uBrRkXPpln51+3jPY6AFny30grNAvKguauDcPPhNV1yR+ylSsQi2gm3 +Rs4pgtlxFLMfZLgT0cbkl+9zk/QUqlpBP8ftUBsOI0ARr8xhFN3cvq9kXGLtJ9hEP9PRaflAFREk +DK3IBIbVcAFZBFoAQOdE9zy0+F5bQrznPGaZg4Dzhcx33qMDUTgHtWoy+k3ePGQMEtmoTTLgQywW +OIkXEoFqqGi9GKJXUT1KYi5NsigaYqu7FoN4Qsvs61pMUEfZSPP2AFwkA8uNFbmb9uxcxaGHCA8i +3i9VM6yOLIrP +-----END CERTIFICATE----- diff --git a/tests/AttestationVerificationTest/assets/test_no_attestation_ext_certs.pem b/tests/AttestationVerificationTest/assets/test_no_attestation_ext_certs.pem new file mode 100644 index 000000000000..6d261fae47cf --- /dev/null +++ b/tests/AttestationVerificationTest/assets/test_no_attestation_ext_certs.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFoDCCA4igAwIBAgIQTfpKgAsLZJhp2V4xUriMADANBgkqhkiG9w0BAQ0FADBp +MQswCQYDVQQGEwJVUzEUMBIGA1UECgwLR29vZ2xlIEluYy4xFzAVBgNVBAsMDkFu +ZHJvaWQgVGhpbmdzMSswKQYDVQQDDCJBbmRyb2lkIFRoaW5ncyBBdHRlc3RhdGlv +biBSb290IENBMCAXDTE3MDYyMTIwMjQzN1oYDzIwNTcwNjExMjAyNDM3WjBpMQsw +CQYDVQQGEwJVUzEUMBIGA1UECgwLR29vZ2xlIEluYy4xFzAVBgNVBAsMDkFuZHJv +aWQgVGhpbmdzMSswKQYDVQQDDCJBbmRyb2lkIFRoaW5ncyBBdHRlc3RhdGlvbiBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuO82oerGivb9 +G9bWyM8Pg0y6SOnAC8/8b92dp1v4Npnc+QpjPRUKgn8lzjQ9Jo6IGY3OShRBiQYl +bbZYkfJnC5HtqbOETdPLZclErVE/G6Oda1IeZWvQVMjNImEYOLL5ct2RxiPttd8v +SLyOSNFPf5/SeFqX/La0NcmXMOvPSrTW3qO34brnC+ih7mlpJFLz6Up93N3Umxsl +IElz2wCG72t6k3+caWLyIPVgIPmsQrfTeBK/hN5dAJgAN65BsTevLHRP9J610wj3 +RagSIK1NdTuJRnr5ZyTQrwE2nA8H3IJ7/eo6IlGhXPwLKDhbdxYygPxdlCq6Rl96 +aVLjfpqDPtJ9ow+QKZuEDbYJ4z4olNXC6O5G7vqnCuULA/2E7y7DZObjzXOrdx2z +9YKd8BrIDMTN/5mmw2us8tywiaQhbl8vOtjU+A+iBBnkj/wt9TYyLKopdrDlo5mz +wy5l750HOkVZXC3VkeECnp+9duSHdS4qeUf/W1j9nPM7kY0HFLPUVX9AFVp2JXnC +iKZC32GQAVsDc1iyAZWAVTqA7E0fBHhk9jUnA0W9b5Lq06oW95ngNR1MIFY871i8 +aLHCBpIix8DuMe8NB9spCIP6WCQqGiWQQpzbeuBPtoi424xwZTO4oectTd77bs9V +Rvunn49fz308KnoWjk/by1N7gWyTb38CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMDQ1I0RKwFCI+Fy9uIIJ/HrXuqu +MA0GCSqGSIb3DQEBDQUAA4ICAQB09qkyEpEDocdN5pPeXqtjj9d0AXREUGH2LhnC +z9KZcUFR+JskwEMHCaOENOmKI3zWRmxT7d8cVywwGk+ExE7EBQoeHlh3Yo44M8aj +ZL7RHCvHRYsePhAJkYpJ02IMR60TV+1jhMqE8+BnqFivS7kft4t295EyrnLRZE3b +Nfc0t011j02RwUrioR57mdvS9EZBRnMQkobhn+jWt9O+V3mtplW+1A2n4ec6uni1 +2MMgAWHuO1sKVYd5Sp4JMUpNnfmQAMnNiOMF6VxkpaoF1lZWo4TrLxuDKJG3O8h1 +fByjCpNVY8kOvvYEadbldzh6Agy/3ppb9yfG7X7FtHr1ghNjuNT6w5VgvbRtoRja +/ZSKuJMaKm5emMWNkls/cwVSPJIvTOzPTeYK1BKSyAL2LDJ93HI7x8h79/Q7gKRi +kL8qT7GW2FqpWTK0253sJHqCJJP4A5Rxtf2+Afwqadfc6Ga4jJHb7rPXngz4j1ZB +gl5yjXgWF9wHGxqrjKWe2EA3d47BC4HG3Rf5L56KQiRPhTqTk5vtZwtwLRLFDLt7 +Hdff13O1oLhn+2z9xkASUL3rFE/qWajZP7fk3CvzcuXwKDTZomIC4nNaglx4nLdj +lHhOq+6ON8MZC46sLStD+D4a9A1HOoihJgI/yGGkwdrp4KQIveRkEBO/x9v3NNBE +bMwG9w== +-----END CERTIFICATE----- diff --git a/tests/AttestationVerificationTest/assets/test_root_certs.pem b/tests/AttestationVerificationTest/assets/test_root_certs.pem new file mode 100644 index 000000000000..c51851fe3da5 --- /dev/null +++ b/tests/AttestationVerificationTest/assets/test_root_certs.pem @@ -0,0 +1,61 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV +BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYy +ODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS +Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7 +tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj +nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq +C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ +oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O +JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg +sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi +igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M +RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E +aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um +AGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYD +VR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lk +Lmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQAD +ggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfB +Pb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00m +qC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rY +DBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPm +QUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4u +JU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyD +CdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79Iy +ZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxD +qwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23Uaic +MDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1 +wDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFHDCCAwSgAwIBAgIJANUP8luj8tazMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV +BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTkxMTIyMjAzNzU4WhcNMzQxMTE4MjAz +NzU4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS +Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7 +tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj +nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq +C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ +oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O +JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg +sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi +igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M +RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E +aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um +AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud +IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBOMaBc8oumXb2voc7XCWnu +XKhBBK3e2KMGz39t7lA3XXRe2ZLLAkLM5y3J7tURkf5a1SutfdOyXAmeE6SRo83U +h6WszodmMkxK5GM4JGrnt4pBisu5igXEydaW7qq2CdC6DOGjG+mEkN8/TA6p3cno +L/sPyz6evdjLlSeJ8rFBH6xWyIZCbrcpYEJzXaUOEaxxXxgYz5/cTiVKN2M1G2ok +QBUIYSY6bjEL4aUN5cfo7ogP3UvliEo3Eo0YgwuzR2v0KR6C1cZqZJSTnghIC/vA +D32KdNQ+c3N+vl2OTsUVMC1GiWkngNx1OO1+kXW+YTnnTUOtOIswUP/Vqd5SYgAI +mMAfY8U9/iIgkQj6T2W6FsScy94IN9fFhE1UtzmLoBIuUFsVXJMTz+Jucth+IqoW +Fua9v1R93/k98p41pjtFX+H8DslVgfP097vju4KDlqN64xV1grw3ZLl4CiOe/A91 +oeLm2UHOq6wn3esB4r2EIQKb6jTVGu5sYCcdWpXr0AUVqcABPdgL+H7qJguBw09o +jm6xNIrw2OocrDKsudk/okr/AwqEyPKw9WnMlQgLIKw1rODG2NvU9oR3GVGdMkUB +ZutL8VuFkERQGt6vQ2OCw0sV47VMkuYbacK/xyZFiRcrPJPb41zgbQj9XAEyLKCH +ex0SdDrx+tWUDqG8At2JHA== +-----END CERTIFICATE----- diff --git a/tests/AttestationVerificationTest/assets/test_virtual_device_attestation_certs.pem b/tests/AttestationVerificationTest/assets/test_virtual_device_attestation_certs.pem new file mode 100644 index 000000000000..282771000bf7 --- /dev/null +++ b/tests/AttestationVerificationTest/assets/test_virtual_device_attestation_certs.pem @@ -0,0 +1,50 @@ +-----BEGIN CERTIFICATE----- +MIIC7DCCApGgAwIBAgIBATAKBggqhkjOPQQDAjCBiDELMAkGA1UEBhMCVVMxEzAR +BgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAoMDEdvb2dsZSwgSW5jLjEQMA4GA1UE +CwwHQW5kcm9pZDE7MDkGA1UEAwwyQW5kcm9pZCBLZXlzdG9yZSBTb2Z0d2FyZSBB +dHRlc3RhdGlvbiBJbnRlcm1lZGlhdGUwHhcNNzAwMTAxMDAwMDAwWhcNNjkxMjMx +MjM1OTU5WjAfMR0wGwYDVQQDDBRBbmRyb2lkIEtleXN0b3JlIEtleTBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABEYtCH28qu+St0F0TixVsQz0L/Y7DcRHgYAU98E6 +edwOpACFmmseYxMjvmZv/4jURSG2/Z0J1s3A/qFzIY96/tyjggFSMIIBTjALBgNV +HQ8EBAMCB4AwggEcBgorBgEEAdZ5AgERBIIBDDCCAQgCAQQKAQACASkKAQAECXBs +YXllcjQ1NgQAMIHqoQgxBgIBAgIBA6IDAgEDowQCAgEApQgxBgIBBAIBBqoDAgEB +v4N3AgUAv4U9CAIGAX8DoY9Qv4U+AwIBAL+FQEwwSgQgAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAABAQAKAQIEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAv4VBBQIDAa2wv4VCBQIDAxUbv4VFRwRFMEMxHTAbBBZjb20uZ29v +Z2xlLmF0dGVzdGF0aW9uAgEBMSIEIDqslV0SVHQBmP11cfMv7kT4nm6pchC7dRKa +iM9vYebVMAAwHwYDVR0jBBgwFoAUP/ys1hqxOp6BILjVJRzFZbsekakwCgYIKoZI +zj0EAwIDSQAwRgIhAMzs7gWWBIITpeLeEEx9B8ihdhkFqpMGlsYLRO01ZIOeAiEA +uKs9xfK3fIOpVAhDmsrp+zE8KUwyvqCU/IS13tXz7Ng= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICeDCCAh6gAwIBAgICEAEwCgYIKoZIzj0EAwIwgZgxCzAJBgNVBAYTAlVTMRMw +EQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYD +VQQKDAxHb29nbGUsIEluYy4xEDAOBgNVBAsMB0FuZHJvaWQxMzAxBgNVBAMMKkFu +ZHJvaWQgS2V5c3RvcmUgU29mdHdhcmUgQXR0ZXN0YXRpb24gUm9vdDAeFw0xNjAx +MTEwMDQ2MDlaFw0yNjAxMDgwMDQ2MDlaMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE +CAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMR29vZ2xlLCBJbmMuMRAwDgYDVQQLDAdB +bmRyb2lkMTswOQYDVQQDDDJBbmRyb2lkIEtleXN0b3JlIFNvZnR3YXJlIEF0dGVz +dGF0aW9uIEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOue +efhCY1msyyqRTImGzHCtkGaTgqlzJhP+rMv4ISdMIXSXSir+pblNf2bU4GUQZjW8 +U7ego6ZxWD7bPhGuEBSjZjBkMB0GA1UdDgQWBBQ//KzWGrE6noEguNUlHMVlux6R +qTAfBgNVHSMEGDAWgBTIrel3TEXDo88NFhDkeUM6IVowzzASBgNVHRMBAf8ECDAG +AQH/AgEAMA4GA1UdDwEB/wQEAwIChDAKBggqhkjOPQQDAgNIADBFAiBLipt77oK8 +wDOHri/AiZi03cONqycqRZ9pDMfDktQPjgIhAO7aAV229DLp1IQ7YkyUBO86fMy9 +Xvsiu+f+uXc/WT/7 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICizCCAjKgAwIBAgIJAKIFntEOQ1tXMAoGCCqGSM49BAMCMIGYMQswCQYDVQQG +EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmll +dzEVMBMGA1UECgwMR29vZ2xlLCBJbmMuMRAwDgYDVQQLDAdBbmRyb2lkMTMwMQYD +VQQDDCpBbmRyb2lkIEtleXN0b3JlIFNvZnR3YXJlIEF0dGVzdGF0aW9uIFJvb3Qw +HhcNMTYwMTExMDA0MzUwWhcNMzYwMTA2MDA0MzUwWjCBmDELMAkGA1UEBhMCVVMx +EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT +BgNVBAoMDEdvb2dsZSwgSW5jLjEQMA4GA1UECwwHQW5kcm9pZDEzMDEGA1UEAwwq +QW5kcm9pZCBLZXlzdG9yZSBTb2Z0d2FyZSBBdHRlc3RhdGlvbiBSb290MFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAE7l1ex+HA220Dpn7mthvsTWpdamguD/9/SQ59 +dx9EIm29sa/6FsvHrcV30lacqrewLVQBXT5DKyqO107sSHVBpKNjMGEwHQYDVR0O +BBYEFMit6XdMRcOjzw0WEOR5QzohWjDPMB8GA1UdIwQYMBaAFMit6XdMRcOjzw0W +EOR5QzohWjDPMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgKEMAoGCCqG +SM49BAMCA0cAMEQCIDUho++LNEYenNVg8x1YiSBq3KNlQfYNns6KGYxmSGB7AiBN +C/NR2TB8fVvaNTQdqEcbY6WFZTytTySn502vQX3xvw== +-----END CERTIFICATE----- diff --git a/tests/AttestationVerificationTest/src/android/security/attestationverification/PeerDeviceSystemAttestationVerificationTest.kt b/tests/AttestationVerificationTest/src/android/security/attestationverification/PeerDeviceSystemAttestationVerificationTest.kt new file mode 100644 index 000000000000..32c2230e4880 --- /dev/null +++ b/tests/AttestationVerificationTest/src/android/security/attestationverification/PeerDeviceSystemAttestationVerificationTest.kt @@ -0,0 +1,161 @@ +package android.security.attestationverification + +import android.app.Activity +import android.os.Bundle +import android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE +import android.security.attestationverification.AttestationVerificationManager.PARAM_PUBLIC_KEY +import android.security.attestationverification.AttestationVerificationManager.PROFILE_PEER_DEVICE +import android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE +import android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE +import android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY +import android.security.attestationverification.AttestationVerificationManager.TYPE_UNKNOWN +import androidx.test.ext.junit.rules.ActivityScenarioRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import java.io.ByteArrayOutputStream +import java.security.cert.CertificateFactory +import java.util.concurrent.CompletableFuture +import java.util.concurrent.TimeUnit + +/** Test for system-defined attestation verifiers. */ +@SmallTest +@RunWith(AndroidJUnit4::class) +class PeerDeviceSystemAttestationVerificationTest { + + @get:Rule + val rule = ActivityScenarioRule(TestActivity::class.java) + + private val certifcateFactory = CertificateFactory.getInstance("X.509") + private lateinit var activity: Activity + private lateinit var avm: AttestationVerificationManager + private lateinit var invalidAttestationByteArray: ByteArray + + @Before + fun setup() { + rule.getScenario().onActivity { + avm = it.getSystemService(AttestationVerificationManager::class.java) + activity = it + } + invalidAttestationByteArray = TEST_ATTESTATION_CERT_FILENAME.fromPEMFileToByteArray() + } + + @Test + fun verifyAttestation_returnsFailureWrongBindingType() { + val future = CompletableFuture<Int>() + val profile = AttestationProfile(PROFILE_PEER_DEVICE) + avm.verifyAttestation(profile, TYPE_UNKNOWN, Bundle(), + invalidAttestationByteArray, activity.mainExecutor) { result, _ -> + future.complete(result) + } + + assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE) + } + + @Test + fun verifyAttestation_returnsFailureEmptyRequirements() { + val future = CompletableFuture<Int>() + val profile = AttestationProfile(PROFILE_PEER_DEVICE) + avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), + invalidAttestationByteArray, activity.mainExecutor) { result, _ -> + future.complete(result) + } + + assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE) + } + + @Test + fun verifyAttestation_returnsFailureMismatchBindingType() { + val future = CompletableFuture<Int>() + val profile = AttestationProfile(PROFILE_PEER_DEVICE) + val publicKeyRequirements = Bundle() + publicKeyRequirements.putByteArray(PARAM_PUBLIC_KEY, "publicKeyStr".encodeToByteArray()) + avm.verifyAttestation(profile, TYPE_CHALLENGE, publicKeyRequirements, + invalidAttestationByteArray, activity.mainExecutor) { result, _ -> + future.complete(result) + } + + assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE) + + val future2 = CompletableFuture<Int>() + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "challengeStr".encodeToByteArray()) + avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, challengeRequirements, + invalidAttestationByteArray, activity.mainExecutor) { result, _ -> + future2.complete(result) + } + + assertThat(future2.getSoon()).isEqualTo(RESULT_FAILURE) + } + + @Test + fun verifyAttestation_returnsFailureWrongResourceKey() { + val future = CompletableFuture<Int>() + val profile = AttestationProfile(PROFILE_PEER_DEVICE) + val wrongKeyRequirements = Bundle() + wrongKeyRequirements.putByteArray("wrongReqKey", "publicKeyStr".encodeToByteArray()) + avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, wrongKeyRequirements, + invalidAttestationByteArray, activity.mainExecutor) { result, _ -> + future.complete(result) + } + + assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE) + } + + @Test + fun verifyAttestation_returnsFailureEmptyAttestation() { + val future = CompletableFuture<Int>() + val profile = AttestationProfile(PROFILE_PEER_DEVICE) + val requirements = Bundle() + requirements.putByteArray(PARAM_PUBLIC_KEY, "publicKeyStr".encodeToByteArray()) + avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, requirements, ByteArray(0), + activity.mainExecutor) { result, _ -> + future.complete(result) + } + + assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE) + } + + @Test + fun verifyAttestation_returnsFailureTrustAnchorMismatch() { + val future = CompletableFuture<Int>() + val profile = AttestationProfile(PROFILE_PEER_DEVICE) + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) + avm.verifyAttestation(profile, TYPE_CHALLENGE, challengeRequirements, + invalidAttestationByteArray, activity.mainExecutor) { result, _ -> + future.complete(result) + } + assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE) + } + + private fun <T> CompletableFuture<T>.getSoon(): T { + return this.get(1, TimeUnit.SECONDS) + } + + private fun String.fromPEMFileToByteArray(): ByteArray { + val certs = certifcateFactory.generateCertificates( + InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets() + .open(this)) + val bos = ByteArrayOutputStream() + certs.forEach { + bos.write(it.encoded) + } + return bos.toByteArray() + } + + class TestActivity : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + } + + companion object { + private const val TEST_ATTESTATION_CERT_FILENAME = "test_attestation_wrong_root_certs.pem" + } +} diff --git a/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt b/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt index 62902929fcd5..169effaa45ca 100644 --- a/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt +++ b/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt @@ -12,8 +12,8 @@ import org.junit.Test import org.junit.runner.RunWith import com.google.common.truth.Truth.assertThat import android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE -import android.security.attestationverification.AttestationVerificationManager.PROFILE_PEER_DEVICE import android.security.attestationverification.AttestationVerificationManager.PROFILE_SELF_TRUSTED +import android.security.attestationverification.AttestationVerificationManager.PROFILE_UNKNOWN import android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE import android.security.attestationverification.AttestationVerificationManager.RESULT_SUCCESS import android.security.attestationverification.AttestationVerificationManager.RESULT_UNKNOWN @@ -52,7 +52,7 @@ class SystemAttestationVerificationTest { @Test fun verifyAttestation_returnsUnknown() { val future = CompletableFuture<Int>() - val profile = AttestationProfile(PROFILE_PEER_DEVICE) + val profile = AttestationProfile(PROFILE_UNKNOWN) avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0), activity.mainExecutor) { result, _ -> future.complete(result) @@ -137,7 +137,7 @@ class SystemAttestationVerificationTest { @Test fun verifyToken_returnsUnknown() { val future = CompletableFuture<Int>() - val profile = AttestationProfile(PROFILE_PEER_DEVICE) + val profile = AttestationProfile(PROFILE_SELF_TRUSTED) avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0), activity.mainExecutor) { _, token -> val result = avm.verifyToken(profile, TYPE_PUBLIC_KEY, Bundle(), token, null) @@ -150,7 +150,7 @@ class SystemAttestationVerificationTest { @Test fun verifyToken_tooBigMaxAgeThrows() { val future = CompletableFuture<VerificationToken>() - val profile = AttestationProfile(PROFILE_PEER_DEVICE) + val profile = AttestationProfile(PROFILE_SELF_TRUSTED) avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0), activity.mainExecutor) { _, token -> future.complete(token) diff --git a/tests/AttestationVerificationTest/src/com/android/server/security/AndroidKeystoreAttestationVerificationAttributesTest.java b/tests/AttestationVerificationTest/src/com/android/server/security/AndroidKeystoreAttestationVerificationAttributesTest.java new file mode 100644 index 000000000000..0d15fe72920a --- /dev/null +++ b/tests/AttestationVerificationTest/src/com/android/server/security/AndroidKeystoreAttestationVerificationAttributesTest.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.security; + +import static com.google.common.truth.Truth.assertThat; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.hamcrest.CoreMatchers; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** Test for data class holding parsed X509Certificate attestation attributes. */ +@RunWith(AndroidJUnit4.class) +public class AndroidKeystoreAttestationVerificationAttributesTest { + @Rule public ExpectedException mException = ExpectedException.none(); + private static final String TEST_PHYSCIAL_DEVICE_CERTS = + "test_attestation_wrong_root_certs.pem"; + private static final String TEST_PHYSICAL_DEVICE_CERTS_2 = + "test_attestation_with_root_certs.pem"; + private static final String TEST_VIRTUAL_DEVICE_CERTS = + "test_virtual_device_attestation_certs.pem"; + private static final String TEST_CERT_NO_ATTESTATION_EXTENSION = + "test_no_attestation_ext_certs.pem"; + private static final String TEST_CERTS_NO_ATTESTATION_EXTENSION_2 = + "test_root_certs.pem"; + + + private CertificateFactory mFactory; + private AndroidKeystoreAttestationVerificationAttributes mPhysicalDeviceAttributes; + private AndroidKeystoreAttestationVerificationAttributes mPhysicalDeviceAttributes2; + private AndroidKeystoreAttestationVerificationAttributes mVirtualDeviceAttributes; + + @Before + public void setUp() throws Exception { + mFactory = CertificateFactory.getInstance("X.509"); + mPhysicalDeviceAttributes = + AndroidKeystoreAttestationVerificationAttributes.fromCertificate( + generateCertificate(TEST_PHYSCIAL_DEVICE_CERTS)); + mPhysicalDeviceAttributes2 = + AndroidKeystoreAttestationVerificationAttributes.fromCertificate( + generateCertificates(TEST_PHYSICAL_DEVICE_CERTS_2).get(0)); + mVirtualDeviceAttributes = + AndroidKeystoreAttestationVerificationAttributes.fromCertificate( + generateCertificates(TEST_VIRTUAL_DEVICE_CERTS).get(0)); + } + + @Test + public void parseCertificate_noAttestationExtension() throws Exception { + List<X509Certificate> certsNoAttestation = + generateCertificates(TEST_CERTS_NO_ATTESTATION_EXTENSION_2); + certsNoAttestation.add(generateCertificate(TEST_CERT_NO_ATTESTATION_EXTENSION)); + for (X509Certificate cert: certsNoAttestation) { + mException.expect(CertificateEncodingException.class); + mException.expectMessage( + CoreMatchers.containsString("No attestation extension found in certificate.")); + + AndroidKeystoreAttestationVerificationAttributes.fromCertificate(cert); + } + } + + @Test + public void parseCertificate_attestationLevel() { + assertThat(mPhysicalDeviceAttributes.getAttestationVersion()).isEqualTo(3); + assertThat(mPhysicalDeviceAttributes2.getAttestationVersion()).isEqualTo(3); + assertThat(mVirtualDeviceAttributes.getAttestationVersion()).isEqualTo(4); + } + + @Test + public void parseCertificate_attestationSecurityLevel() { + assertThat(mPhysicalDeviceAttributes.getAttestationSecurityLevel()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT); + assertThat(mPhysicalDeviceAttributes2.getAttestationSecurityLevel()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT); + assertThat(mVirtualDeviceAttributes.getAttestationSecurityLevel()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.SOFTWARE); + } + + @Test + public void parseCertificate_isAttestationHardwareBacked() { + assertThat(mPhysicalDeviceAttributes.isAttestationHardwareBacked()).isTrue(); + assertThat(mPhysicalDeviceAttributes2.isAttestationHardwareBacked()).isTrue(); + assertThat(mVirtualDeviceAttributes.isAttestationHardwareBacked()).isFalse(); + } + + @Test + public void parseCertificate_keymasterLevel() { + assertThat(mPhysicalDeviceAttributes.getKeymasterVersion()).isEqualTo(4); + assertThat(mPhysicalDeviceAttributes2.getKeymasterVersion()).isEqualTo(4); + assertThat(mVirtualDeviceAttributes.getKeymasterVersion()).isEqualTo(41); + } + + @Test + public void parseCertificate_keymasterSecurityLevel() { + assertThat(mPhysicalDeviceAttributes.getKeymasterSecurityLevel()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT); + assertThat(mPhysicalDeviceAttributes2.getKeymasterSecurityLevel()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT); + assertThat(mVirtualDeviceAttributes.getKeymasterSecurityLevel()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.SOFTWARE); + } + + @Test + public void parseCertificate_isKeymasterHardwareBacked() { + assertThat(mPhysicalDeviceAttributes.isKeymasterHardwareBacked()).isTrue(); + assertThat(mPhysicalDeviceAttributes2.isKeymasterHardwareBacked()).isTrue(); + assertThat(mVirtualDeviceAttributes.isKeymasterHardwareBacked()).isFalse(); + } + + @Test + public void parseCertificate_attestationChallenge() { + assertThat(mPhysicalDeviceAttributes.getAttestationChallenge().toByteArray()).isEqualTo( + "abc".getBytes(UTF_8)); + assertThat(mPhysicalDeviceAttributes2.getAttestationChallenge().toByteArray()).isEqualTo( + "player456".getBytes(UTF_8)); + assertThat(mVirtualDeviceAttributes.getAttestationChallenge().toByteArray()).isEqualTo( + "player456".getBytes(UTF_8)); + } + + @Test + public void parseCertificate_verifiedBootState() { + assertThat(mPhysicalDeviceAttributes.getVerifiedBootState()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.VerifiedBootState.UNVERIFIED); + assertThat(mPhysicalDeviceAttributes2.getVerifiedBootState()).isEqualTo( + AndroidKeystoreAttestationVerificationAttributes.VerifiedBootState.VERIFIED); + assertThat(mVirtualDeviceAttributes.getVerifiedBootState()).isNull(); + } + + @Test + public void parseCertificate_keyBootPatchLevel() { + assertThat(mPhysicalDeviceAttributes.getKeyBootPatchLevel()).isEqualTo(201907); + assertThat(mPhysicalDeviceAttributes2.getKeyBootPatchLevel()).isEqualTo(20220105); + } + + @Test + public void parseCertificate_keyBootPatchLevelNotSetException() { + mException.expect(IllegalStateException.class); + mException.expectMessage( + CoreMatchers.containsString("KeyBootPatchLevel is not set.")); + + mVirtualDeviceAttributes.getKeyBootPatchLevel(); + } + + @Test + public void parseCertificate_keyOsPatchLevel() { + assertThat(mPhysicalDeviceAttributes.getKeyOsPatchLevel()).isEqualTo(201907); + assertThat(mPhysicalDeviceAttributes2.getKeyOsPatchLevel()).isEqualTo(202201); + } + + @Test + public void parseCertificate_keyOsPatchLevelNotSetException() { + mException.expect(IllegalStateException.class); + mException.expectMessage( + CoreMatchers.containsString("KeyOsPatchLevel is not set.")); + + mVirtualDeviceAttributes.getKeyOsPatchLevel(); + } + + @Test + public void parseCertificate_keyVendorPatchLevel() { + assertThat(mPhysicalDeviceAttributes.getKeyVendorPatchLevel()).isEqualTo(201907); + assertThat(mPhysicalDeviceAttributes2.getKeyVendorPatchLevel()).isEqualTo(20220105); + } + + @Test + public void parseCertificate_keyVendorPatchLevelNotSetException() { + mException.expect(IllegalStateException.class); + mException.expectMessage( + CoreMatchers.containsString("KeyVendorPatchLevel is not set.")); + + mVirtualDeviceAttributes.getKeyVendorPatchLevel(); + } + + @Test + public void parseCertificate_keyAuthenticatorType() { + assertThat(mPhysicalDeviceAttributes.getKeyAuthenticatorType()).isEqualTo(0); + assertThat(mPhysicalDeviceAttributes2.getKeyAuthenticatorType()).isEqualTo(0); + } + + @Test + public void parseCertificate_keyOsVersion() { + assertThat(mPhysicalDeviceAttributes.getKeyOsVersion()).isEqualTo(0); + assertThat(mPhysicalDeviceAttributes2.getKeyOsVersion()).isEqualTo(120000); + } + + @Test + public void parseCertificate_keyOsVersionNotSetException() { + mException.expect(IllegalStateException.class); + mException.expectMessage( + CoreMatchers.containsString("KeyOsVersion is not set.")); + + mVirtualDeviceAttributes.getKeyOsVersion(); + } + + @Test + public void parseCertificate_verifiedBootHash() { + assertThat(mPhysicalDeviceAttributes.getVerifiedBootHash()).isNotEmpty(); + assertThat(mPhysicalDeviceAttributes2.getVerifiedBootHash()).isNotEmpty(); + } + + @Test + public void parseCertificate_verifiedBootKey() { + assertThat(mPhysicalDeviceAttributes.getVerifiedBootKey()).isNotEmpty(); + assertThat(mPhysicalDeviceAttributes2.getVerifiedBootKey()).isNotEmpty(); + } + + @Test + public void parseCertificate_isVerifiedBootLocked() { + assertThat(mPhysicalDeviceAttributes.isVerifiedBootLocked()).isFalse(); + assertThat(mPhysicalDeviceAttributes2.isVerifiedBootLocked()).isTrue(); + } + + @Test + public void parseCertificate_isVerifiedBootLockedNotSetException() { + mException.expect(IllegalStateException.class); + mException.expectMessage( + CoreMatchers.containsString("VerifiedBootLocked is not set.")); + + mVirtualDeviceAttributes.isVerifiedBootLocked(); + } + + @Test + public void parseCertificate_applicationPackageNameVersion() { + assertThat(mPhysicalDeviceAttributes.getApplicationPackageNameVersion()).isNotEmpty(); + } + + @Test + public void parseCertificate_applicationCertificateDigests() { + assertThat(mPhysicalDeviceAttributes.getApplicationCertificateDigests()).isNotEmpty(); + } + + @Test + public void parseCertificate_valuesNotSet() { + assertThat(mPhysicalDeviceAttributes.getDeviceBrand()).isNull(); + assertThat(mPhysicalDeviceAttributes.getDeviceName()).isNull(); + assertThat(mPhysicalDeviceAttributes.getDeviceProductName()).isNull(); + assertThat(mPhysicalDeviceAttributes.isKeyAllowedForAllApplications()).isFalse(); + assertThat(mPhysicalDeviceAttributes2.getDeviceBrand()).isNull(); + assertThat(mPhysicalDeviceAttributes2.getDeviceName()).isNull(); + assertThat(mPhysicalDeviceAttributes2.getDeviceProductName()).isNull(); + assertThat(mPhysicalDeviceAttributes2.isKeyAllowedForAllApplications()).isFalse(); + } + + @Test + public void parseCertificate_keyRequiresUnlockedDeviceNotSetException() { + mException.expect(IllegalStateException.class); + mException.expectMessage( + CoreMatchers.containsString("KeyRequiresUnlockedDevice is not set.")); + + mPhysicalDeviceAttributes.isKeyRequiresUnlockedDevice(); + } + + private X509Certificate generateCertificate(String certificateString) + throws Exception { + return generateCertificates(certificateString).get(0); + } + + private List<X509Certificate> generateCertificates(String certificateString) + throws Exception { + Collection<? extends Certificate> certificates = mFactory.generateCertificates( + InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets() + .open(certificateString)); + + ArrayList<X509Certificate> x509Certs = new ArrayList<>(); + for (Certificate cert : certificates) { + x509Certs.add((X509Certificate) cert); + } + return x509Certs; + } +} diff --git a/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt b/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt new file mode 100644 index 000000000000..45f2e5c6fdf7 --- /dev/null +++ b/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt @@ -0,0 +1,175 @@ +package com.android.server.security + +import android.app.Activity +import android.content.Context +import android.os.Bundle +import android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE +import android.security.attestationverification.AttestationVerificationManager.PARAM_PUBLIC_KEY +import android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE +import android.security.attestationverification.AttestationVerificationManager.RESULT_SUCCESS +import android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE +import android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations +import java.io.ByteArrayOutputStream +import java.security.cert.Certificate +import java.security.cert.CertificateFactory +import java.security.cert.TrustAnchor +import java.security.cert.X509Certificate +import java.time.LocalDate + +/** Test for Peer Device attestation verifier. */ +@SmallTest +@RunWith(AndroidJUnit4::class) +class AttestationVerificationPeerDeviceVerifierTest { + private val certificateFactory = CertificateFactory.getInstance("X.509") + @Mock private lateinit var context: Context + private lateinit var trustAnchors: HashSet<TrustAnchor> + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + val rootCerts = TEST_ROOT_CERT_FILENAME.fromPEMFileToCerts() + trustAnchors = HashSet<TrustAnchor>() + rootCerts.forEach { + trustAnchors.add(TrustAnchor(it as X509Certificate, null)) + } + } + + @Test + fun verifyAttestation_returnsSuccessTypeChallenge() { + val verifier = AttestationVerificationPeerDeviceVerifier( + context, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 8, 1)) + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) + + val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + assertThat(result).isEqualTo(RESULT_SUCCESS) + } + + @Test + fun verifyAttestation_returnsSuccessLocalPatchOlderThanOneYear() { + val verifier = AttestationVerificationPeerDeviceVerifier( + context, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 1, 1)) + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) + + val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + assertThat(result).isEqualTo(RESULT_SUCCESS) + } + + @Test + fun verifyAttestation_returnsSuccessTypePublicKey() { + val verifier = AttestationVerificationPeerDeviceVerifier( + context, trustAnchors, false, LocalDate.of(2022, 2, 1), + LocalDate.of(2021, 8, 1)) + + val leafCert = + (TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToCerts() as List)[0] + as X509Certificate + val pkRequirements = Bundle() + pkRequirements.putByteArray(PARAM_PUBLIC_KEY, leafCert.publicKey.encoded) + + val result = verifier.verifyAttestation( + TYPE_PUBLIC_KEY, pkRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + assertThat(result).isEqualTo(RESULT_SUCCESS) + } + + @Test + fun verifyAttestation_returnsFailurePatchDateNotWithinOneYearLocalPatch() { + val verifier = AttestationVerificationPeerDeviceVerifier( + context, trustAnchors, false, LocalDate.of(2023, 3, 1), + LocalDate.of(2023, 2, 1)) + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) + + val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + assertThat(result).isEqualTo(RESULT_FAILURE) + } + + @Test + fun verifyAttestation_returnsFailureTrustedAnchorEmpty() { + val verifier = AttestationVerificationPeerDeviceVerifier( + context, HashSet(), false, LocalDate.of(2022, 1, 1), + LocalDate.of(2022, 1, 1)) + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) + + val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + assertThat(result).isEqualTo(RESULT_FAILURE) + } + + @Test + fun verifyAttestation_returnsFailureTrustedAnchorMismatch() { + val badTrustAnchorsCerts = TEST_ATTESTATION_CERT_FILENAME.fromPEMFileToCerts() + val badTrustAnchors = HashSet<TrustAnchor>() + badTrustAnchorsCerts.forEach { + badTrustAnchors.add(TrustAnchor(it as X509Certificate, null)) + } + + val verifier = AttestationVerificationPeerDeviceVerifier( + context, badTrustAnchors, false, LocalDate.of(2022, 1, 1), + LocalDate.of(2022, 1, 1)) + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray()) + + val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + assertThat(result).isEqualTo(RESULT_FAILURE) + } + + fun verifyAttestation_returnsFailureChallenge() { + val verifier = AttestationVerificationPeerDeviceVerifier( + context, trustAnchors, false, LocalDate.of(2022, 1, 1), + LocalDate.of(2022, 1, 1)) + val challengeRequirements = Bundle() + challengeRequirements.putByteArray(PARAM_CHALLENGE, "wrong".encodeToByteArray()) + + val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements, + TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray()) + assertThat(result).isEqualTo(RESULT_FAILURE) + } + + private fun String.fromPEMFileToCerts(): Collection<Certificate> { + return certificateFactory.generateCertificates( + InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets() + .open(this)) + } + + private fun String.fromPEMFileToByteArray(): ByteArray { + val certs = this.fromPEMFileToCerts() + val bos = ByteArrayOutputStream() + certs.forEach { + bos.write(it.encoded) + } + return bos.toByteArray() + } + + class TestActivity : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + } + + companion object { + private const val TEST_ROOT_CERT_FILENAME = "test_root_certs.pem" + private const val TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME = + "test_attestation_with_root_certs.pem" + private const val TEST_ATTESTATION_CERT_FILENAME = "test_attestation_wrong_root_certs.pem" + } +} |