Changeset 236686 in webkit


Ignore:
Timestamp:
Oct 1, 2018 12:47:05 PM (5 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebAuthN] Import a JS CBOR coder
https://bugs.webkit.org/show_bug.cgi?id=189877
<rdar://problem/44701124>

Reviewed by Chris Dumez.

Source/WebKit:

Update MockWebAuthenticationConfiguration to have userCertificateBase64 and intermediateCACertificateBase64
as Local's memeber such that tests can pass those certificates to MockLocalConnection instead of letting it
holds some static ones.

  • UIProcess/API/C/WKWebsiteDataStoreRef.cpp:

(WKWebsiteDataStoreSetWebAuthenticationMockConfiguration):

  • UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:

(WebKit::MockLocalConnection::getAttestation const):

  • UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h:

Tools:

Add logic to only process privateKeyBase64, userCertificateBase64 and intermediateCACertificateBase64
only if acceptAttestation is true.

  • WebKitTestRunner/InjectedBundle/TestRunner.cpp:

(WTR::TestRunner::setWebAuthenticationMockConfiguration):

LayoutTests:

This patch import a 3rd party JS CBOR coder from https://github.com/paroga/cbor-js.
The library is MIT licensed, which should be fine to use within WebKit.

As a benefit from the library, tests are updated to check CBOR binaries.

  • http/wpt/credential-management/credentialscontainer-store-basics.https.html:
  • http/wpt/webauthn/idl.https.html:
  • http/wpt/webauthn/public-key-credential-create-failure-local.https.html:
  • http/wpt/webauthn/public-key-credential-create-success-local.https.html:
  • http/wpt/webauthn/public-key-credential-get-failure-local.https.html:
  • http/wpt/webauthn/public-key-credential-get-success-local.https.html:
  • http/wpt/webauthn/resources/cbor.js: Added.
  • http/wpt/webauthn/resources/util.js:
Location:
trunk
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r236678 r236686  
     12018-10-01  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Import a JS CBOR coder
     4        https://bugs.webkit.org/show_bug.cgi?id=189877
     5        <rdar://problem/44701124>
     6
     7        Reviewed by Chris Dumez.
     8
     9        This patch import a 3rd party JS CBOR coder from https://github.com/paroga/cbor-js.
     10        The library is MIT licensed, which should be fine to use within WebKit.
     11
     12        As a benefit from the library, tests are updated to check CBOR binaries.
     13
     14        * http/wpt/credential-management/credentialscontainer-store-basics.https.html:
     15        * http/wpt/webauthn/idl.https.html:
     16        * http/wpt/webauthn/public-key-credential-create-failure-local.https.html:
     17        * http/wpt/webauthn/public-key-credential-create-success-local.https.html:
     18        * http/wpt/webauthn/public-key-credential-get-failure-local.https.html:
     19        * http/wpt/webauthn/public-key-credential-get-success-local.https.html:
     20        * http/wpt/webauthn/resources/cbor.js: Added.
     21        * http/wpt/webauthn/resources/util.js:
     22
    1232018-10-01  Daniel Bates  <dabates@apple.com>
    224
  • trunk/LayoutTests/http/wpt/credential-management/credentialscontainer-store-basics.https.html

    r236625 r236686  
    88        "PH76c0+WFOzZKslPyyFse4goGIW2R7k9VHLPEZl5nfnBgEVFh5zev+/xpHQIvuq6" +
    99        "RQ==";
     10    const testAttestationCertificateBase64 =
     11        "MIIB6jCCAZCgAwIBAgIGAWHAxcjvMAoGCCqGSM49BAMCMFMxJzAlBgNVBAMMHkJh" +
     12        "c2ljIEF0dGVzdGF0aW9uIFVzZXIgU3ViIENBMTETMBEGA1UECgwKQXBwbGUgSW5j" +
     13        "LjETMBEGA1UECAwKQ2FsaWZvcm5pYTAeFw0xODAyMjMwMzM3MjJaFw0xODAyMjQw" +
     14        "MzQ3MjJaMGoxIjAgBgNVBAMMGTAwMDA4MDEwLTAwMEE0OUEyMzBBMDIxM0ExGjAY" +
     15        "BgNVBAsMEUJBQSBDZXJ0aWZpY2F0aW9uMRMwEQYDVQQKDApBcHBsZSBJbmMuMRMw" +
     16        "EQYDVQQIDApDYWxpZm9ybmlhMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvCje" +
     17        "Pzr6Sg76XMoHuGabPaG6zjpLFL8Zd8/74Hh5PcL2Zq+o+f7ENXX+7nEXXYt0S8Ux" +
     18        "5TIRw4hgbfxXQbWLEqM5MDcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBPAw" +
     19        "FwYJKoZIhvdjZAgCBAowCKEGBAR0ZXN0MAoGCCqGSM49BAMCA0gAMEUCIAlK8A8I" +
     20        "k43TbvKuYGHZs1DTgpTwmKTBvIUw5bwgZuYnAiEAtuJjDLKbGNJAJFMi5deEBqno" +
     21        "pBTCqbfbDJccfyQpjnY=";
     22    const testAttestationIssuingCACertificateBase64 =
     23        "MIICIzCCAaigAwIBAgIIeNjhG9tnDGgwCgYIKoZIzj0EAwIwUzEnMCUGA1UEAwwe" +
     24        "QmFzaWMgQXR0ZXN0YXRpb24gVXNlciBSb290IENBMRMwEQYDVQQKDApBcHBsZSBJ" +
     25        "bmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMB4XDTE3MDQyMDAwNDIwMFoXDTMyMDMy" +
     26        "MjAwMDAwMFowUzEnMCUGA1UEAwweQmFzaWMgQXR0ZXN0YXRpb24gVXNlciBTdWIg" +
     27        "Q0ExMRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMFkw" +
     28        "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoSZ/1t9eBAEVp5a8PrXacmbGb8zNC1X3" +
     29        "StLI9YO6Y0CL7blHmSGmjGWTwD4Q+i0J2BY3+bPHTGRyA9jGB3MSbaNmMGQwEgYD" +
     30        "VR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBSD5aMhnrB0w/lhkP2XTiMQdqSj" +
     31        "8jAdBgNVHQ4EFgQU5mWf1DYLTXUdQ9xmOH/uqeNSD80wDgYDVR0PAQH/BAQDAgEG" +
     32        "MAoGCCqGSM49BAMCA2kAMGYCMQC3M360LLtJS60Z9q3vVjJxMgMcFQ1roGTUcKqv" +
     33        "W+4hJ4CeJjySXTgq6IEHn/yWab4CMQCm5NnK6SOSK+AqWum9lL87W3E6AA1f2TvJ" +
     34        "/hgok/34jr93nhS87tOQNdxDS8zyiqw=";
    1035    const testRpId = "localhost";
    1136    function asciiToUint8Array(str)
     
    1540            chars.push(str.charCodeAt(i));
    1641        return new Uint8Array(chars);
    17     }
    18     function hexStringToUint8Array(hexString)
    19     {
    20         if (hexString.length % 2 != 0)
    21             throw "Invalid hexString";
    22         var arrayBuffer = new Uint8Array(hexString.length / 2);
    23 
    24         for (var i = 0; i < hexString.length; i += 2) {
    25             var byteValue = parseInt(hexString.substr(i, 2), 16);
    26             if (byteValue == NaN)
    27                 throw "Invalid hexString";
    28             arrayBuffer[i/2] = byteValue;
    29         }
    30 
    31         return arrayBuffer;
    3242    }
    3343
     
    4959        // A mock attestation object
    5060        if (window.testRunner)
    51             testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: true, privateKeyBase64: testES256PrivateKeyBase64 } });
     61            testRunner.setWebAuthenticationMockConfiguration({
     62                local: {
     63                    acceptAuthentication: true,
     64                    acceptAttestation: true,
     65                    privateKeyBase64: testES256PrivateKeyBase64,
     66                    userCertificateBase64: testAttestationCertificateBase64,
     67                    intermediateCACertificateBase64: testAttestationIssuingCACertificateBase64
     68                }
     69            });
    5270        const credential = await navigator.credentials.create(options);
    5371
  • trunk/LayoutTests/http/wpt/webauthn/idl.https.html

    r236625 r236686  
    2121<script>
    2222if (window.testRunner)
    23     testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: true, privateKeyBase64: testES256PrivateKeyBase64 } });
     23    testRunner.setWebAuthenticationMockConfiguration({
     24        local: {
     25            acceptAuthentication: true,
     26            acceptAttestation: true,
     27            privateKeyBase64: testES256PrivateKeyBase64,
     28            userCertificateBase64: testAttestationCertificateBase64,
     29            intermediateCACertificateBase64: testAttestationIssuingCACertificateBase64
     30        }
     31    });
    2432
    2533promise_test(async () => {
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html

    r236625 r236686  
    77    // Default mock configuration. Tests need to override if they need different configuration.
    88    if (window.testRunner)
    9         testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false, privateKeyBase64: "" } });
     9        testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
    1010
    1111    promise_test(t => {
     
    4040                challenge: asciiToUint8Array("123456"),
    4141                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
    42                 excludeCredentials: [{ type: "public-key", id: Base64URL.parse(testCredentialIdBase64url) }]
     42                excludeCredentials: [{ type: "public-key", id: Base64URL.parse(testCredentialIdBase64) }]
    4343            }
    4444        };
     
    6565                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
    6666                excludeCredentials: [
    67                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["usb"] },
    68                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["nfc"] },
    69                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["ble"] },
    70                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["internal"] }
     67                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
     68                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
     69                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] },
     70                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] }
    7171                ]
    7272            }
     
    114114        };
    115115        if (window.testRunner)
    116             testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false, privateKeyBase64: "" } });
     116            testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });
    117117        return promiseRejects(t, "UnknownError", navigator.credentials.create(options), "Unknown internal error.");
    118118    }, "PublicKeyCredential's [[create]] without attestation in a mock local authenticator.");
     
    134134        };
    135135        if (window.testRunner) {
    136             testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false, privateKeyBase64: "" } });
     136            testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });
    137137            testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);
    138138        }
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-success-local.https.html

    r236481 r236686  
    44<script src="/resources/testharnessreport.js"></script>
    55<script src="./resources/util.js"></script>
     6<script src="./resources/cbor.js"></script>
    67<script>
    78    // Default mock configuration. Tests need to override if they need different configuration.
    89    if (window.testRunner)
    9         testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: true, privateKeyBase64: testES256PrivateKeyBase64 } });
     10        testRunner.setWebAuthenticationMockConfiguration({
     11            local: {
     12                acceptAuthentication: true,
     13                acceptAttestation: true,
     14                privateKeyBase64: testES256PrivateKeyBase64,
     15                userCertificateBase64: testAttestationCertificateBase64,
     16                intermediateCACertificateBase64: testAttestationIssuingCACertificateBase64
     17            }
     18        });
    1019
    1120    function checkResult(credential)
     
    1827
    1928        // Check respond
    20         assert_equals(credential.id, testCredentialIdBase64url);
     29        assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testCredentialIdBase64));
    2130        assert_equals(credential.type, 'public-key');
    22         assert_equals(bytesToHexString(credential.rawId), "48c4971e7805ee110eb04940ef70b7458fbc6d1e");
     31        assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testCredentialIdBase64));
    2332        assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.create","challenge":"MTIzNDU2","origin":"https://localhost:9443","hashAlgorithm":"SHA-256"}');
    24         // FIXME(): Check attestation object
    2533        assert_throws("NotSupportedError", () => { credential.getClientExtensionResults() });
     34
     35        // Check attestation
     36        const attestationObject = CBOR.decode(credential.response.attestationObject);
     37        assert_equals(attestationObject.fmt, "Apple");
     38        // Check authData
     39        const authData = decodeAuthData(attestationObject.authData);
     40        assert_equals(bytesToHexString(authData.rpIdHash), "49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763");
     41        assert_equals(authData.flags, 69);
     42        assert_equals(authData.counter, 0);
     43        assert_equals(bytesToHexString(authData.aaguid), "00000000000000000000000000000000");
     44        assert_array_equals(authData.credentialID, Base64URL.parse(testCredentialIdBase64));
     45        // Check self attestation
     46        assert_equals(attestationObject.attStmt.alg, -7);
     47        assert_true(checkPublicKey(authData.publicKey));
     48        assert_equals(attestationObject.attStmt.x5c.length, 2);
     49        assert_array_equals(attestationObject.attStmt.x5c[0], Base64URL.parse(testAttestationCertificateBase64));
     50        assert_array_equals(attestationObject.attStmt.x5c[1], Base64URL.parse(testAttestationIssuingCACertificateBase64));
     51
     52        // Check signature
     53        let publicKeyData = new Uint8Array(65);
     54        publicKeyData[0] = 0x04;
     55        publicKeyData.set(authData.publicKey['-2'], 1);
     56        publicKeyData.set(authData.publicKey['-3'], 33);
     57        return crypto.subtle.importKey("raw", publicKeyData, { name: "ECDSA", namedCurve: "P-256" }, false, ['verify']).then( publicKey => {
     58            return crypto.subtle.verify({name: "ECDSA", hash: "SHA-256"}, publicKey, extractRawSignature(attestationObject.attStmt.sig), attestationObject.authData).then( verified => {
     59                assert_true(verified);
     60            });
     61        });
    2662    }
    2763
     
    83119                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
    84120                excludeCredentials: [
    85                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["usb"] },
    86                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["nfc"] },
    87                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["ble"] }
     121                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
     122                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
     123                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] }
    88124                ]
    89125            }
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html

    r236625 r236686  
    77    // Default mock configuration. Tests need to override if they need different configuration.
    88    if (window.testRunner)
    9         testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false, privateKeyBase64: "" } });
     9        testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
    1010
    1111    promise_test(t => {
     
    1414                challenge: asciiToUint8Array("123456"),
    1515                allowCredentials: [
    16                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["usb"] },
    17                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["nfc"] },
    18                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["ble"] },
    19                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["internal"] }
     16                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
     17                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
     18                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] },
     19                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] }
    2020                ]
    2121            }
  • trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-success-local.https.html

    r236481 r236686  
    77    // Default mock configuration. Tests need to override if they need different configuration.
    88    if (window.testRunner)
    9         testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false, privateKeyBase64: "" } });
     9        testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: true, acceptAttestation: false } });
    1010
    1111    function checkResult(credential)
     
    1515
    1616         // Check respond
    17         assert_equals(credential.id, testCredentialIdBase64url);
     17        assert_array_equals(Base64URL.parse(credential.id), Base64URL.parse(testCredentialIdBase64));
    1818        assert_equals(credential.type, 'public-key');
    19         assert_equals(bytesToHexString(credential.rawId), "48c4971e7805ee110eb04940ef70b7458fbc6d1e");
     19        assert_array_equals(new Uint8Array(credential.rawId), Base64URL.parse(testCredentialIdBase64));
    2020        assert_equals(bytesToASCIIString(credential.response.clientDataJSON), '{"type":"webauthn.get","challenge":"MTIzNDU2","origin":"https://localhost:9443","hashAlgorithm":"SHA-256"}');
    2121        assert_equals(bytesToHexString(credential.response.userHandle), "00010203040506070809");
     
    2828
    2929        // Check signature
    30         return crypto.subtle.importKey("raw", Base64URL.parse(testES256PublicKeyBase64url), { name: "ECDSA", namedCurve: "P-256" }, false, ['verify']).then( publicKey => {
     30        return crypto.subtle.importKey("raw", Base64URL.parse(testES256PublicKeyBase64), { name: "ECDSA", namedCurve: "P-256" }, false, ['verify']).then( publicKey => {
    3131            return crypto.subtle.digest("sha-256", credential.response.clientDataJSON).then ( hash => {
    3232                // credential.response.signature is in ASN.1 and WebCrypto expect signatures provides in r|s.
     
    5959                allowCredentials: [
    6060                    { type: "public-key", id: Base64URL.parse(testUserhandleBase64), transports: ["internal"] },
    61                     { type: "public-key", id: Base64URL.parse(testCredentialIdBase64url), transports: ["internal"] }
     61                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] }
    6262                ]
    6363            }
  • trunk/LayoutTests/http/wpt/webauthn/resources/util.js

    r236625 r236686  
    1 const testCredentialIdBase64url = "SMSXHngF7hEOsElA73C3RY-8bR4";
     1const testCredentialIdBase64 = "SMSXHngF7hEOsElA73C3RY+8bR4=";
    22const testES256PrivateKeyBase64 =
    33    "BDj/zxSkzKgaBuS3cdWDF558of8AaIpgFpsjF/Qm1749VBJPgqUIwfhWHJ91nb7U" +
    44    "PH76c0+WFOzZKslPyyFse4goGIW2R7k9VHLPEZl5nfnBgEVFh5zev+/xpHQIvuq6" +
    55    "RQ==";
    6 const testES256PublicKeyBase64url =
    7     "BDj_zxSkzKgaBuS3cdWDF558of8AaIpgFpsjF_Qm1749VBJPgqUIwfhWHJ91nb7U" +
    8     "PH76c0-WFOzZKslPyyFse4g";
     6const testES256PublicKeyBase64 =
     7    "BDj/zxSkzKgaBuS3cdWDF558of8AaIpgFpsjF/Qm1749VBJPgqUIwfhWHJ91nb7U" +
     8    "PH76c0+WFOzZKslPyyFse4g=";
    99const testRpId = "localhost";
    1010const testUserhandleBase64 = "AAECAwQFBgcICQ==";
     11const testAttestationCertificateBase64 =
     12    "MIIB6jCCAZCgAwIBAgIGAWHAxcjvMAoGCCqGSM49BAMCMFMxJzAlBgNVBAMMHkJh" +
     13    "c2ljIEF0dGVzdGF0aW9uIFVzZXIgU3ViIENBMTETMBEGA1UECgwKQXBwbGUgSW5j" +
     14    "LjETMBEGA1UECAwKQ2FsaWZvcm5pYTAeFw0xODAyMjMwMzM3MjJaFw0xODAyMjQw" +
     15    "MzQ3MjJaMGoxIjAgBgNVBAMMGTAwMDA4MDEwLTAwMEE0OUEyMzBBMDIxM0ExGjAY" +
     16    "BgNVBAsMEUJBQSBDZXJ0aWZpY2F0aW9uMRMwEQYDVQQKDApBcHBsZSBJbmMuMRMw" +
     17    "EQYDVQQIDApDYWxpZm9ybmlhMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvCje" +
     18    "Pzr6Sg76XMoHuGabPaG6zjpLFL8Zd8/74Hh5PcL2Zq+o+f7ENXX+7nEXXYt0S8Ux" +
     19    "5TIRw4hgbfxXQbWLEqM5MDcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBPAw" +
     20    "FwYJKoZIhvdjZAgCBAowCKEGBAR0ZXN0MAoGCCqGSM49BAMCA0gAMEUCIAlK8A8I" +
     21    "k43TbvKuYGHZs1DTgpTwmKTBvIUw5bwgZuYnAiEAtuJjDLKbGNJAJFMi5deEBqno" +
     22    "pBTCqbfbDJccfyQpjnY=";
     23const testAttestationIssuingCACertificateBase64 =
     24    "MIICIzCCAaigAwIBAgIIeNjhG9tnDGgwCgYIKoZIzj0EAwIwUzEnMCUGA1UEAwwe" +
     25    "QmFzaWMgQXR0ZXN0YXRpb24gVXNlciBSb290IENBMRMwEQYDVQQKDApBcHBsZSBJ" +
     26    "bmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMB4XDTE3MDQyMDAwNDIwMFoXDTMyMDMy" +
     27    "MjAwMDAwMFowUzEnMCUGA1UEAwweQmFzaWMgQXR0ZXN0YXRpb24gVXNlciBTdWIg" +
     28    "Q0ExMRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMFkw" +
     29    "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoSZ/1t9eBAEVp5a8PrXacmbGb8zNC1X3" +
     30    "StLI9YO6Y0CL7blHmSGmjGWTwD4Q+i0J2BY3+bPHTGRyA9jGB3MSbaNmMGQwEgYD" +
     31    "VR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBSD5aMhnrB0w/lhkP2XTiMQdqSj" +
     32    "8jAdBgNVHQ4EFgQU5mWf1DYLTXUdQ9xmOH/uqeNSD80wDgYDVR0PAQH/BAQDAgEG" +
     33    "MAoGCCqGSM49BAMCA2kAMGYCMQC3M360LLtJS60Z9q3vVjJxMgMcFQ1roGTUcKqv" +
     34    "W+4hJ4CeJjySXTgq6IEHn/yWab4CMQCm5NnK6SOSK+AqWum9lL87W3E6AA1f2TvJ" +
     35    "/hgok/34jr93nhS87tOQNdxDS8zyiqw=";
    1136
    1237const RESOURCES_DIR = "/WebKit/webauthn/resources/";
     
    126151    pos = pos + size;
    127152
    128     // FIXME(): Add CBOR decoder to parse the public key.
     153    // Public Key
     154    authDataObject.publicKey = CBOR.decode(authDataUint8Array.slice(pos).buffer);
     155    if (!authDataObject.publicKey)
     156        return { };
    129157
    130158    // Assume no extensions.
     
    180208    });
    181209}
     210
     211// COSE Key Format: https://www.w3.org/TR/webauthn/#sctn-encoded-credPubKey-examples.
     212function checkPublicKey(publicKey)
     213{
     214    if (publicKey['1'] != 2)
     215        return false;
     216    if (publicKey['3'] != -7)
     217        return false;
     218    if (publicKey['-1'] != 1)
     219        return false;
     220    if (publicKey['-2'].byteLength != 32)
     221        return false;
     222    if (publicKey['-3'].byteLength != 32)
     223        return false;
     224    return true;
     225}
  • trunk/Source/WebKit/ChangeLog

    r236680 r236686  
     12018-10-01  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Import a JS CBOR coder
     4        https://bugs.webkit.org/show_bug.cgi?id=189877
     5        <rdar://problem/44701124>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Update MockWebAuthenticationConfiguration to have userCertificateBase64 and intermediateCACertificateBase64
     10        as Local's memeber such that tests can pass those certificates to MockLocalConnection instead of letting it
     11        holds some static ones.
     12
     13        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
     14        (WKWebsiteDataStoreSetWebAuthenticationMockConfiguration):
     15        * UIProcess/WebAuthentication/Mock/MockLocalConnection.mm:
     16        (WebKit::MockLocalConnection::getAttestation const):
     17        * UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h:
     18
    1192018-10-01  Chris Dumez  <cdumez@apple.com>
    220
  • trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp

    r236625 r236686  
    583583        local.acceptAuthentication = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(localRef, adoptWK(WKStringCreateWithUTF8CString("AcceptAuthentication")).get())));
    584584        local.acceptAttestation = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(localRef, adoptWK(WKStringCreateWithUTF8CString("AcceptAttestation")).get())));
    585         local.privateKeyBase64 = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(localRef, adoptWK(WKStringCreateWithUTF8CString("PrivateKeyBase64")).get())))->string();
     585        if (local.acceptAttestation) {
     586            local.privateKeyBase64 = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(localRef, adoptWK(WKStringCreateWithUTF8CString("PrivateKeyBase64")).get())))->string();
     587            local.userCertificateBase64 = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(localRef, adoptWK(WKStringCreateWithUTF8CString("UserCertificateBase64")).get())))->string();
     588            local.intermediateCACertificateBase64 = WebKit::toImpl(static_cast<WKStringRef>(WKDictionaryGetItemForKey(localRef, adoptWK(WKStringCreateWithUTF8CString("IntermediateCACertificateBase64")).get())))->string();
     589        }
    586590        configuration.local = WTFMove(local);
    587591    }
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.mm

    r236625 r236686  
    3737namespace WebKit {
    3838
    39 namespace MockLocalConnectionInternal {
    40 const char* const testAttestationCertificateBase64 =
    41     "MIIB6jCCAZCgAwIBAgIGAWHAxcjvMAoGCCqGSM49BAMCMFMxJzAlBgNVBAMMHkJh"
    42     "c2ljIEF0dGVzdGF0aW9uIFVzZXIgU3ViIENBMTETMBEGA1UECgwKQXBwbGUgSW5j"
    43     "LjETMBEGA1UECAwKQ2FsaWZvcm5pYTAeFw0xODAyMjMwMzM3MjJaFw0xODAyMjQw"
    44     "MzQ3MjJaMGoxIjAgBgNVBAMMGTAwMDA4MDEwLTAwMEE0OUEyMzBBMDIxM0ExGjAY"
    45     "BgNVBAsMEUJBQSBDZXJ0aWZpY2F0aW9uMRMwEQYDVQQKDApBcHBsZSBJbmMuMRMw"
    46     "EQYDVQQIDApDYWxpZm9ybmlhMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvCje"
    47     "Pzr6Sg76XMoHuGabPaG6zjpLFL8Zd8/74Hh5PcL2Zq+o+f7ENXX+7nEXXYt0S8Ux"
    48     "5TIRw4hgbfxXQbWLEqM5MDcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBPAw"
    49     "FwYJKoZIhvdjZAgCBAowCKEGBAR0ZXN0MAoGCCqGSM49BAMCA0gAMEUCIAlK8A8I"
    50     "k43TbvKuYGHZs1DTgpTwmKTBvIUw5bwgZuYnAiEAtuJjDLKbGNJAJFMi5deEBqno"
    51     "pBTCqbfbDJccfyQpjnY=";
    52 const char* const testAttestationIssuingCACertificateBase64 =
    53     "MIICIzCCAaigAwIBAgIIeNjhG9tnDGgwCgYIKoZIzj0EAwIwUzEnMCUGA1UEAwwe"
    54     "QmFzaWMgQXR0ZXN0YXRpb24gVXNlciBSb290IENBMRMwEQYDVQQKDApBcHBsZSBJ"
    55     "bmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMB4XDTE3MDQyMDAwNDIwMFoXDTMyMDMy"
    56     "MjAwMDAwMFowUzEnMCUGA1UEAwweQmFzaWMgQXR0ZXN0YXRpb24gVXNlciBTdWIg"
    57     "Q0ExMRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMFkw"
    58     "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoSZ/1t9eBAEVp5a8PrXacmbGb8zNC1X3"
    59     "StLI9YO6Y0CL7blHmSGmjGWTwD4Q+i0J2BY3+bPHTGRyA9jGB3MSbaNmMGQwEgYD"
    60     "VR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBSD5aMhnrB0w/lhkP2XTiMQdqSj"
    61     "8jAdBgNVHQ4EFgQU5mWf1DYLTXUdQ9xmOH/uqeNSD80wDgYDVR0PAQH/BAQDAgEG"
    62     "MAoGCCqGSM49BAMCA2kAMGYCMQC3M360LLtJS60Z9q3vVjJxMgMcFQ1roGTUcKqv"
    63     "W+4hJ4CeJjySXTgq6IEHn/yWab4CMQCm5NnK6SOSK+AqWum9lL87W3E6AA1f2TvJ"
    64     "/hgok/34jr93nhS87tOQNdxDS8zyiqw=";
    65 }
    66 
    6739MockLocalConnection::MockLocalConnection(const MockWebAuthenticationConfiguration& configuration)
    6840    : m_configuration(configuration)
     
    9870void MockLocalConnection::getAttestation(const String& rpId, const String& username, const Vector<uint8_t>& hash, AttestationCallback&& callback) const
    9971{
    100     using namespace MockLocalConnectionInternal;
    101 
    10272    // Mock async operations.
    10373    RunLoop::main().dispatch([configuration = m_configuration, rpId, username, hash, callback = WTFMove(callback)]() mutable {
     
    132102        ASSERT_UNUSED(status, !status);
    133103
    134         // Construct dummy certificates. The content of certificates is not important. We need them to present to
    135         // check the CBOR encoding procedure.
    136         auto attestationCertificate = adoptCF(SecCertificateCreateWithData(NULL, (__bridge CFDataRef)adoptNS([[NSData alloc] initWithBase64EncodedString:[NSString stringWithCString:testAttestationCertificateBase64 encoding:NSASCIIStringEncoding] options:NSDataBase64DecodingIgnoreUnknownCharacters]).get()));
    137         auto attestationIssuingCACertificate = adoptCF(SecCertificateCreateWithData(NULL, (__bridge CFDataRef)adoptNS([[NSData alloc] initWithBase64EncodedString:[NSString stringWithCString:testAttestationIssuingCACertificateBase64 encoding:NSASCIIStringEncoding] options:NSDataBase64DecodingIgnoreUnknownCharacters]).get()));
     104        auto attestationCertificate = adoptCF(SecCertificateCreateWithData(NULL, (__bridge CFDataRef)adoptNS([[NSData alloc] initWithBase64EncodedString:configuration.local->userCertificateBase64 options:NSDataBase64DecodingIgnoreUnknownCharacters]).get()));
     105        auto attestationIssuingCACertificate = adoptCF(SecCertificateCreateWithData(NULL, (__bridge CFDataRef)adoptNS([[NSData alloc] initWithBase64EncodedString:configuration.local->intermediateCACertificateBase64 options:NSDataBase64DecodingIgnoreUnknownCharacters]).get()));
    138106
    139107        callback(key.get(), [NSArray arrayWithObjects: (__bridge id)attestationCertificate.get(), (__bridge id)attestationIssuingCACertificate.get(), nil], NULL);
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h

    r236625 r236686  
    3535        bool acceptAttestation { false };
    3636        String privateKeyBase64;
     37        String userCertificateBase64;
     38        String intermediateCACertificateBase64;
    3739    };
    3840
  • trunk/Tools/ChangeLog

    r236680 r236686  
     12018-10-01  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthN] Import a JS CBOR coder
     4        https://bugs.webkit.org/show_bug.cgi?id=189877
     5        <rdar://problem/44701124>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Add logic to only process privateKeyBase64, userCertificateBase64 and intermediateCACertificateBase64
     10        only if acceptAttestation is true.
     11
     12        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
     13        (WTR::TestRunner::setWebAuthenticationMockConfiguration):
     14
    1152018-10-01  Chris Dumez  <cdumez@apple.com>
    216
  • trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp

    r236625 r236686  
    23812381        bool acceptAttestation = JSValueToBoolean(context, acceptAttestationValue);
    23822382
    2383         JSRetainPtr<JSStringRef> privateKeyBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("privateKeyBase64"));
    2384         JSValueRef privateKeyBase64Value = JSObjectGetProperty(context, local, privateKeyBase64PropertyName.get(), 0);
    2385         if (!JSValueIsString(context, privateKeyBase64Value))
    2386             return;
    2387 
    23882383        Vector<WKRetainPtr<WKStringRef>> localKeys;
    23892384        Vector<WKRetainPtr<WKTypeRef>> localValues;
     
    23922387        localKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("AcceptAttestation") });
    23932388        localValues.append(adoptWK(WKBooleanCreate(acceptAttestation)).get());
    2394         localKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("PrivateKeyBase64") });
    2395         localValues.append(toWK(adopt(JSValueToStringCopy(context, privateKeyBase64Value, 0)).get()));
     2389
     2390        if (acceptAttestation) {
     2391            JSRetainPtr<JSStringRef> privateKeyBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("privateKeyBase64"));
     2392            JSValueRef privateKeyBase64Value = JSObjectGetProperty(context, local, privateKeyBase64PropertyName.get(), 0);
     2393            if (!JSValueIsString(context, privateKeyBase64Value))
     2394                return;
     2395
     2396            JSRetainPtr<JSStringRef> userCertificateBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("userCertificateBase64"));
     2397            JSValueRef userCertificateBase64Value = JSObjectGetProperty(context, local, userCertificateBase64PropertyName.get(), 0);
     2398            if (!JSValueIsString(context, userCertificateBase64Value))
     2399                return;
     2400
     2401            JSRetainPtr<JSStringRef> intermediateCACertificateBase64PropertyName(Adopt, JSStringCreateWithUTF8CString("intermediateCACertificateBase64"));
     2402            JSValueRef intermediateCACertificateBase64Value = JSObjectGetProperty(context, local, intermediateCACertificateBase64PropertyName.get(), 0);
     2403            if (!JSValueIsString(context, intermediateCACertificateBase64Value))
     2404            return;
     2405
     2406            localKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("PrivateKeyBase64") });
     2407            localValues.append(toWK(adopt(JSValueToStringCopy(context, privateKeyBase64Value, 0)).get()));
     2408            localKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("UserCertificateBase64") });
     2409            localValues.append(toWK(adopt(JSValueToStringCopy(context, userCertificateBase64Value, 0)).get()));
     2410            localKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("IntermediateCACertificateBase64") });
     2411            localValues.append(toWK(adopt(JSValueToStringCopy(context, intermediateCACertificateBase64Value, 0)).get()));
     2412        }
    23962413
    23972414        Vector<WKStringRef> rawLocalKeys;
Note: See TracChangeset for help on using the changeset viewer.