diff --git a/rust/profiles/src/profiles.rs b/rust/profiles/src/profiles.rs index 3d240f1c..2d2ccda6 100644 --- a/rust/profiles/src/profiles.rs +++ b/rust/profiles/src/profiles.rs @@ -56,10 +56,6 @@ pub struct Session { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct TokenSession { pub session: Session, - /// The body field committed rather than revealed, ordered last so the - /// committed run is a suffix (REQ-COMMON-22). `None` for a public client, - /// whose request hides nothing and is revealed whole. - pub secret_field: Option<&'static str>, /// The header lines a Platform Verifier requires, each exactly once with /// its value: `host` and `content-type`, lowercased as the wire spells /// them. Every other header is the runtime's own, save the names @@ -120,7 +116,6 @@ pub const X: Profile = Profile { path: "/2/oauth2/token", request_line: "POST /2/oauth2/token ", }, - secret_field: None, required_headers: &[ "host: api.x.com", "content-type: application/x-www-form-urlencoded", @@ -153,7 +148,6 @@ pub const GITHUB: Profile = Profile { path: "/login/oauth/access_token", request_line: "POST /login/oauth/access_token ", }, - secret_field: None, required_headers: &[ "host: github.com", "content-type: application/x-www-form-urlencoded", diff --git a/scripts/regen-ceremony-profiles.py b/scripts/regen-ceremony-profiles.py index 6357a21f..8d6b447c 100755 --- a/scripts/regen-ceremony-profiles.py +++ b/scripts/regen-ceremony-profiles.py @@ -231,8 +231,6 @@ def validate(spec: dict[str, Any]) -> None: safe(session["path"], "path") if name == "token": required_headers(session) - if session["secretField"] is not None: - safe(session["secretField"], "secretField") if name == "identity": safe(session["idField"], "idField") safe(session["handleField"], "handleField") @@ -353,22 +351,6 @@ def gen_sol(spec: dict[str, Any]) -> str: f' bytes internal constant FORBIDDEN_REQUEST_HEADERS = "{escaped(crlf(forbidden_headers(spec)))}";' ) - lines += [ - "", - " /// @dev How many committed ranges the token request carries. A confidential", - " /// client commits its secret and a public client hides nothing, so this", - " /// is one or zero and never a preference.", - "", - ] - for profile in profiles: - token = profile["sessions"].get("token") - if token is None: - continue - count = 0 if token["secretField"] is None else 1 - lines.append( - f" uint256 internal constant {upper(profile['platform'])}_TOKEN_SENT_COMMITMENTS = {count};" - ) - lines += [ "", " /// @dev The two identity members a Platform Verifier reads out of the", @@ -539,10 +521,6 @@ def gen_rust(spec: dict[str, Any]) -> str: "#[derive(Clone, Copy, Debug, PartialEq, Eq)]", "pub struct TokenSession {", " pub session: Session,", - " /// The body field committed rather than revealed, ordered last so the", - " /// committed run is a suffix (REQ-COMMON-22). `None` for a public client,", - " /// whose request hides nothing and is revealed whole.", - " pub secret_field: Option<&'static str>,", " /// The header lines a Platform Verifier requires, each exactly once with", " /// its value: `host` and `content-type`, lowercased as the wire spells", " /// them. Every other header is the runtime's own, save the names", @@ -596,7 +574,6 @@ def gen_rust(spec: dict[str, Any]) -> str: else: lines.append(" token: Some(TokenSession {") lines += rust_session(token, 8) - lines.append(f" secret_field: {rust_str(token['secretField'])},") lines += rust_array("required_headers: ", required_headers(token), " ", ",") lines.append(" }),") @@ -720,8 +697,6 @@ def gen_ts(spec: dict[str, Any]) -> str: "", "export interface TokenSession {", " readonly session: Session", - " /** The body field committed rather than revealed, or null. */", - " readonly secretField: string | null", " /** The header lines a Platform Verifier requires, each exactly once with", " * its value: `host` and `content-type`. Every other header is the", " * runtime's own, save the names `FORBIDDEN_REQUEST_HEADERS` lists.", @@ -759,7 +734,6 @@ def gen_ts(spec: dict[str, Any]) -> str: else: lines.append(" token: {") lines += ts_session(token, 4) - lines.append(f" secretField: {ts_str(token['secretField'])},") lines += ts_array("requiredHeaders: ", required_headers(token), " ", ",") lines.append(" },") diff --git a/solidity/contracts/ceremony/CeremonyProfile.sol b/solidity/contracts/ceremony/CeremonyProfile.sol index da6e8236..abaa97c9 100644 --- a/solidity/contracts/ceremony/CeremonyProfile.sol +++ b/solidity/contracts/ceremony/CeremonyProfile.sol @@ -87,13 +87,6 @@ library CeremonyProfile { bytes internal constant FORBIDDEN_REQUEST_HEADERS = "authorization\r\ncontent-encoding\r\ncookie\r\ntransfer-encoding\r\nx-http-method\r\nx-http-method-override\r\nx-method-override"; - /// @dev How many committed ranges the token request carries. A confidential - /// client commits its secret and a public client hides nothing, so this - /// is one or zero and never a preference. - - uint256 internal constant X_TOKEN_SENT_COMMITMENTS = 0; - uint256 internal constant GITHUB_TOKEN_SENT_COMMITMENTS = 0; - /// @dev The two identity members a Platform Verifier reads out of the /// revealed response bytes (REQ-PLAT-51). diff --git a/solidity/contracts/ceremony/GitHubPlatformVerifier.sol b/solidity/contracts/ceremony/GitHubPlatformVerifier.sol index e5bbbd6d..0eb379c1 100644 --- a/solidity/contracts/ceremony/GitHubPlatformVerifier.sol +++ b/solidity/contracts/ceremony/GitHubPlatformVerifier.sol @@ -95,12 +95,6 @@ contract GitHubPlatformVerifier is TlsNotaryVerifierBase { return CeremonyProfile.AUTHORITY_GITHUB_API; } - /// @dev GitHub's exchange hides no body field, so its request is revealed - /// whole and this direction carries no commitment at all. - function _tokenSentCommitments() internal pure override returns (uint256) { - return CeremonyProfile.GITHUB_TOKEN_SENT_COMMITMENTS; - } - function _tokenRequestLine() internal pure override returns (bytes memory) { return CeremonyProfile.GITHUB_TOKEN_REQUEST_LINE; } diff --git a/solidity/contracts/ceremony/TlsNotaryVerifierBase.sol b/solidity/contracts/ceremony/TlsNotaryVerifierBase.sol index ea844ab0..2c8a9ff3 100644 --- a/solidity/contracts/ceremony/TlsNotaryVerifierBase.sol +++ b/solidity/contracts/ceremony/TlsNotaryVerifierBase.sol @@ -95,7 +95,7 @@ abstract contract TlsNotaryVerifierBase is IPlatformVerifier, PlatformVerifierBa /// @dev The first revealed range does not begin the transcript, so nothing /// says the bytes read as a request line ARE the request line. error RequestLineNotAtOrigin(uint32 start); - /// @dev The token request does not have the exact shape the profile fixes. + /// @dev The token request is not one revealed run with no commitment. error WrongTokenRequestLayout(uint256 revealedRanges, uint256 commitments); /// @dev The head/body separator is missing or ambiguous, so the body cannot /// be located by the framing the server itself parsed. @@ -132,11 +132,6 @@ abstract contract TlsNotaryVerifierBase is IPlatformVerifier, PlatformVerifierBa /// `authorization`, and the framing around the committed value. function _tokenRequiredHeaders() internal pure virtual returns (bytes memory); - /// @dev How many committed ranges the token request carries. Both launch - /// profiles hide no body field, so both answer zero and their - /// requests are revealed whole. - function _tokenSentCommitments() internal pure virtual returns (uint256); - /// @dev Anything the profile checks in the token body beyond the fields /// every profile reads. Default: nothing. function _checkTokenBody(bytes memory body) internal pure virtual {} @@ -332,7 +327,7 @@ abstract contract TlsNotaryVerifierBase is IPlatformVerifier, PlatformVerifierBa // Both stay: REQ-COMMON-21A is about the method and the path, and a // deployment pointed at the wrong endpoint should hear that rather than // that some byte of its request differs. - bytes memory body = _tokenBody(data.sent, data.sentTranscriptLength); + bytes memory body = _tokenBody(data.sent); _checkTokenBody(body); // REQ-COMMON-15A. This is the whole binding between the evidence and @@ -467,10 +462,9 @@ abstract contract TlsNotaryVerifierBase is IPlatformVerifier, PlatformVerifierBa /// real one, and every field below is then read from bytes the /// platform never saw while the platform executed something else. /// - /// So the profile fixes the shape exactly: ONE revealed run beginning - /// at offset 0, and exactly the committed ranges the profile expects. - /// Both launch profiles expect none: the run covers the request - /// through to its signed length, so no body byte is hidden. + /// So the shape is fixed exactly: ONE revealed run beginning at + /// offset 0 and no commitment at all, so the run covers the request + /// through to its signed length and no body byte is hidden. /// /// AND THE HEAD ITSELF, byte for byte. Revealing the headers is not /// checking them: they were public and unconstrained here, while @@ -709,12 +703,8 @@ abstract contract TlsNotaryVerifierBase is IPlatformVerifier, PlatformVerifierBa return a.length == b.length && keccak256(a) == keccak256(b); } - function _tokenBody(CeremonyAttestation.DirectionBlock memory block_, uint32 signedLength) - internal - pure - returns (bytes memory body) - { - if (block_.revealed.length != 1 || block_.commitments.length != _tokenSentCommitments()) { + function _tokenBody(CeremonyAttestation.DirectionBlock memory block_) internal pure returns (bytes memory body) { + if (block_.revealed.length != 1 || block_.commitments.length != 0) { revert WrongTokenRequestLayout(block_.revealed.length, block_.commitments.length); } bytes memory whole = block_.revealed[0].value; @@ -734,12 +724,9 @@ abstract contract TlsNotaryVerifierBase is IPlatformVerifier, PlatformVerifierBa uint256 declared = _checkTokenHead(_slice(whole, 0, at)); at += 4; - // `signedLength` is the whole request and the head is revealed, so the - // remainder is the body. It comes from the signed length rather than - // from the revealed run so that a profile committing part of its body - // is framed by what the notary signed; where a profile commits nothing - // the two are the same number. - if (declared != signedLength - at) revert WrongDeclaredBodyLength(declared, signedLength - at); + // The run is the request whole and the head is revealed, so the + // remainder is the body the platform parsed. + if (declared != whole.length - at) revert WrongDeclaredBodyLength(declared, whole.length - at); body = new bytes(whole.length - at); for (uint256 i = 0; i < body.length; ++i) { diff --git a/solidity/contracts/ceremony/XPlatformVerifier.sol b/solidity/contracts/ceremony/XPlatformVerifier.sol index 6faa1af9..136f3462 100644 --- a/solidity/contracts/ceremony/XPlatformVerifier.sol +++ b/solidity/contracts/ceremony/XPlatformVerifier.sol @@ -75,12 +75,6 @@ contract XPlatformVerifier is TlsNotaryVerifierBase { return CeremonyProfile.AUTHORITY_X_API; } - /// @dev X uses a public client and hides no body field, so its token - /// request is revealed whole. - function _tokenSentCommitments() internal pure override returns (uint256) { - return CeremonyProfile.X_TOKEN_SENT_COMMITMENTS; - } - function _tokenRequestLine() internal pure override returns (bytes memory) { return CeremonyProfile.X_TOKEN_REQUEST_LINE; } diff --git a/solidity/contracts/ceremony/profiles.json b/solidity/contracts/ceremony/profiles.json index 0758f98e..9585df3d 100644 --- a/solidity/contracts/ceremony/profiles.json +++ b/solidity/contracts/ceremony/profiles.json @@ -81,7 +81,6 @@ "authority": "api.x.com", "method": "POST", "path": "/2/oauth2/token", - "secretField": null, "requiredHeaders": [ "host: api.x.com", "content-type: application/x-www-form-urlencoded" @@ -136,7 +135,6 @@ "authority": "github.com", "method": "POST", "path": "/login/oauth/access_token", - "secretField": null, "requiredHeaders": [ "host: github.com", "content-type: application/x-www-form-urlencoded" diff --git a/ts/packages/contracts/src/ceremony/profiles.ts b/ts/packages/contracts/src/ceremony/profiles.ts index 69683d24..f29dc47a 100644 --- a/ts/packages/contracts/src/ceremony/profiles.ts +++ b/ts/packages/contracts/src/ceremony/profiles.ts @@ -39,8 +39,6 @@ export interface Session { export interface TokenSession { readonly session: Session - /** The body field committed rather than revealed, or null. */ - readonly secretField: string | null /** The header lines a Platform Verifier requires, each exactly once with * its value: `host` and `content-type`. Every other header is the * runtime's own, save the names `FORBIDDEN_REQUEST_HEADERS` lists. @@ -89,7 +87,6 @@ export const X: Profile = { path: '/2/oauth2/token', requestLine: 'POST /2/oauth2/token ', }, - secretField: null, requiredHeaders: ['host: api.x.com', 'content-type: application/x-www-form-urlencoded'], }, identity: { @@ -121,7 +118,6 @@ export const GITHUB: Profile = { path: '/login/oauth/access_token', requestLine: 'POST /login/oauth/access_token ', }, - secretField: null, requiredHeaders: ['host: github.com', 'content-type: application/x-www-form-urlencoded'], }, identity: {