diff --git a/java/client/src/org/openqa/selenium/devtools/network/events/SignedExchangeReceived.java b/java/client/src/org/openqa/selenium/devtools/network/events/SignedExchangeReceived.java index 464b6eb7a6d00..bd3e975692723 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/events/SignedExchangeReceived.java +++ b/java/client/src/org/openqa/selenium/devtools/network/events/SignedExchangeReceived.java @@ -8,6 +8,7 @@ import org.openqa.selenium.devtools.network.types.SignedExchangeInfo; import org.openqa.selenium.json.JsonInput; +import java.util.ArrayList; import java.util.List; /** @@ -51,10 +52,26 @@ private static SignedExchangeReceived fromJson(JsonInput input) { case "outerResponse": outerResponse = Response.parseResponse(input); break; + case "header": + header = SignedExchangeHeader.parseResponse(input); + break; + case "securityDetails": + securityDetails = SecurityDetails.parseResponse(input); + break; + case "errors": + input.beginArray(); + errors = new ArrayList<>(); + while (input.hasNext()) { + errors.add(SignedExchangeError.parseResponse(input)); + } + input.endArray(); + break; + default: + input.skipValue(); + break; } } - //TODO: @GED add parse for header, securityDetails, errors info = new SignedExchangeInfo(outerResponse, header, securityDetails, errors); break; diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/CertificateTransparencyCompliance.java b/java/client/src/org/openqa/selenium/devtools/network/types/CertificateTransparencyCompliance.java index 8c14c70fe509b..362e7b462baa3 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/CertificateTransparencyCompliance.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/CertificateTransparencyCompliance.java @@ -1,7 +1,7 @@ package org.openqa.selenium.devtools.network.types; /** - * Created by aohana + * Whether the request complied with Certificate Transparency policy */ public enum CertificateTransparencyCompliance { diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/Response.java b/java/client/src/org/openqa/selenium/devtools/network/types/Response.java index 35cd11e3e0180..53f2da987dc7a 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/Response.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/Response.java @@ -272,7 +272,7 @@ public void setSecurityDetails(SecurityDetails securityDetails) { } public static Response parseResponse(JsonInput input) { - Response redirectResponse; + Response response; input.beginObject(); String responseUrl = null; @@ -368,13 +368,22 @@ public static Response parseResponse(JsonInput input) { case "encodedDataLength": encodedDataLength = input.nextNumber(); break; + case "protocol": + protocol = input.nextString(); + break; + case "securityState": + securityState = SecurityState.valueOf(input.nextString()); + break; + case "securityDetails": + securityDetails = SecurityDetails.parseSecurityDetails(input); + break; default: input.skipValue(); break; } } - //TODO: @GED add parse for timing, protocol, securityState, securityDetails - redirectResponse = + + response = new Response(responseUrl, Integer.valueOf(String.valueOf(status)), statusText, responseHeaders, headersText, mimeType, requestHeaders, requestHeadersText, connectionReused, @@ -382,7 +391,7 @@ public static Response parseResponse(JsonInput input) { Integer.valueOf(String.valueOf(remotePort)), fromDiskCache, fromServiceWorker, Double.valueOf(String.valueOf(encodedDataLength)), timing, protocol, securityState, securityDetails); - return redirectResponse; + return response; } } diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/SecurityDetails.java b/java/client/src/org/openqa/selenium/devtools/network/types/SecurityDetails.java index c80874fc93cb6..e7f2e850dd83c 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/SecurityDetails.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/SecurityDetails.java @@ -1,5 +1,8 @@ package org.openqa.selenium.devtools.network.types; +import org.openqa.selenium.json.JsonInput; + +import java.util.ArrayList; import java.util.List; /** @@ -33,135 +36,311 @@ public class SecurityDetails { private CertificateTransparencyCompliance certificateTransparencyCompliance; - /** Protocol name (e.g. "TLS 1.2" or "QUIC"). */ + public SecurityDetails() { + } + + public SecurityDetails(String protocol, String keyExchange, String keyExchangeGroup, + String cipher, String mac, Integer certificateId, + String subjectName, List sanList, String issuer, + Double validFrom, Double validTo, + List signedCertificateTimestampList, + CertificateTransparencyCompliance certificateTransparencyCompliance) { + this.protocol = protocol; + this.keyExchange = keyExchange; + this.keyExchangeGroup = keyExchangeGroup; + this.cipher = cipher; + this.mac = mac; + this.certificateId = certificateId; + this.subjectName = subjectName; + this.sanList = sanList; + this.issuer = issuer; + this.validFrom = validFrom; + this.validTo = validTo; + this.signedCertificateTimestampList = signedCertificateTimestampList; + this.certificateTransparencyCompliance = certificateTransparencyCompliance; + } + + /** + * Protocol name (e.g. "TLS 1.2" or "QUIC"). + */ public String getProtocol() { return protocol; } - /** Protocol name (e.g. "TLS 1.2" or "QUIC"). */ + /** + * Protocol name (e.g. "TLS 1.2" or "QUIC"). + */ public void setProtocol(String protocol) { this.protocol = protocol; } - /** Key Exchange used by the connection, or the empty string if not applicable. */ + /** + * Key Exchange used by the connection, or the empty string if not applicable. + */ public String getKeyExchange() { return keyExchange; } - /** Key Exchange used by the connection, or the empty string if not applicable. */ + /** + * Key Exchange used by the connection, or the empty string if not applicable. + */ public void setKeyExchange(String keyExchange) { this.keyExchange = keyExchange; } - /** (EC)DH group used by the connection, if applicable. */ + /** + * (EC)DH group used by the connection, if applicable. + */ public String getKeyExchangeGroup() { return keyExchangeGroup; } - /** (EC)DH group used by the connection, if applicable. */ + /** + * (EC)DH group used by the connection, if applicable. + */ public void setKeyExchangeGroup(String keyExchangeGroup) { this.keyExchangeGroup = keyExchangeGroup; } - /** Cipher name. */ + /** + * Cipher name. + */ public String getCipher() { return cipher; } - /** Cipher name. */ + /** + * Cipher name. + */ public void setCipher(String cipher) { this.cipher = cipher; } - /** TLS MAC. Note that AEAD ciphers do not have separate MACs. */ + /** + * TLS MAC. Note that AEAD ciphers do not have separate MACs. + */ public String getMac() { return mac; } - /** TLS MAC. Note that AEAD ciphers do not have separate MACs. */ + /** + * TLS MAC. Note that AEAD ciphers do not have separate MACs. + */ public void setMac(String mac) { this.mac = mac; } - /** Certificate ID value. */ + /** + * Certificate ID value. + */ public Integer getCertificateId() { return certificateId; } - /** Certificate ID value. */ + /** + * Certificate ID value. + */ public void setCertificateId(Integer certificateId) { this.certificateId = certificateId; } - /** Certificate subject name. */ + /** + * Certificate subject name. + */ public String getSubjectName() { return subjectName; } - /** Certificate subject name. */ + /** + * Certificate subject name. + */ public void setSubjectName(String subjectName) { this.subjectName = subjectName; } - /** Subject Alternative Name (SAN) DNS names and IP addresses. */ + /** + * Subject Alternative Name (SAN) DNS names and IP addresses. + */ public List getSanList() { return sanList; } - /** Subject Alternative Name (SAN) DNS names and IP addresses. */ + /** + * Subject Alternative Name (SAN) DNS names and IP addresses. + */ public void setSanList(List sanList) { this.sanList = sanList; } - /** Name of the issuing CA. */ + /** + * Name of the issuing CA. + */ public String getIssuer() { return issuer; } - /** Name of the issuing CA. */ + /** + * Name of the issuing CA. + */ public void setIssuer(String issuer) { this.issuer = issuer; } - /** Certificate valid from date. */ + /** + * Certificate valid from date. + */ public Double getValidFrom() { return validFrom; } - /** Certificate valid from date. */ + /** + * Certificate valid from date. + */ public void setValidFrom(Double validFrom) { this.validFrom = validFrom; } - /** Certificate valid to (expiration) date */ + /** + * Certificate valid to (expiration) date + */ public Double getValidTo() { return validTo; } - /** Certificate valid to (expiration) date */ + /** + * Certificate valid to (expiration) date + */ public void setValidTo(Double validTo) { this.validTo = validTo; } - /** List of signed certificate timestamps (SCTs). */ + /** + * List of signed certificate timestamps (SCTs). + */ public List getSignedCertificateTimestampList() { return signedCertificateTimestampList; } - /** List of signed certificate timestamps (SCTs). */ + /** + * List of signed certificate timestamps (SCTs). + */ public void setSignedCertificateTimestampList( List signedCertificateTimestampList) { this.signedCertificateTimestampList = signedCertificateTimestampList; } - /** Whether the request complied with Certificate Transparency policy */ + /** + * Whether the request complied with Certificate Transparency policy + */ public CertificateTransparencyCompliance getCertificateTransparencyCompliance() { return certificateTransparencyCompliance; } - /** Whether the request complied with Certificate Transparency policy */ + /** + * Whether the request complied with Certificate Transparency policy + */ public void setCertificateTransparencyCompliance( CertificateTransparencyCompliance certificateTransparencyCompliance) { this.certificateTransparencyCompliance = certificateTransparencyCompliance; } + + public static SecurityDetails parseSecurityDetails(JsonInput input) { + + SecurityDetails securityDetails = null; + + String protocol = null; + + String keyExchange = null; + + String keyExchangeGroup = null; + + String cipher = null; + + String mac = null; + + Number certificateId = null; + + String subjectName = null; + + List sanList = null; + + String issuer = null; + + Number validFrom = null; + + Number validTo = null; + + List signedCertificateTimestampList = null; + + CertificateTransparencyCompliance certificateTransparencyCompliance = null; + + input.beginObject(); + + while (input.hasNext()) { + + switch (input.nextName()) { + case "protocol": + protocol = input.nextString(); + break; + case "keyExchange": + keyExchange = input.nextString(); + break; + case "keyExchangeGroup": + keyExchangeGroup = input.nextString(); + break; + case "cipher": + cipher = input.nextString(); + break; + case "mac": + mac = input.nextString(); + break; + case "certificateId": + certificateId = input.nextNumber(); + break; + case "subjectName": + subjectName = input.nextString(); + break; + case "sanList": + input.beginArray(); + sanList = new ArrayList<>(); + while (input.hasNext()) { + sanList.add(input.nextString()); + } + input.endArray(); + break; + case "issuer": + issuer = input.nextString(); + break; + case "validFrom": + validFrom = input.nextNumber(); + break; + case "validTo": + validTo = input.nextNumber(); + break; + case "signedCertificateTimestampList": + input.beginArray(); + signedCertificateTimestampList = new ArrayList<>(); + while (input.hasNext()) { + signedCertificateTimestampList.add(SignedCertificateTimestamp.parseSignedCertificateTimestamp(input)); + } + input.endArray(); + break; + case "certificateTransparencyCompliance": + certificateTransparencyCompliance = CertificateTransparencyCompliance.valueOf(input.nextString()); + break; + default: + input.skipValue(); + break; + } + + } + + return new SecurityDetails(protocol, keyExchange, keyExchangeGroup, cipher, mac, Integer.valueOf(String.valueOf(certificateId)), subjectName, sanList, issuer, + Double.valueOf(String.valueOf(validFrom)), Double.valueOf(String.valueOf(validTo)), signedCertificateTimestampList, certificateTransparencyCompliance); + } + + public static SecurityDetails parseResponse(JsonInput input) { + //TODO: @GED implement parser + return null; + } } diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/SecurityState.java b/java/client/src/org/openqa/selenium/devtools/network/types/SecurityState.java index 398b79daebf79..1a7ee3704826d 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/SecurityState.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/SecurityState.java @@ -1,7 +1,7 @@ package org.openqa.selenium.devtools.network.types; /** - * Created by aohana + * The security level of a page or resource */ public enum SecurityState { diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/SignedCertificateTimestamp.java b/java/client/src/org/openqa/selenium/devtools/network/types/SignedCertificateTimestamp.java index 61645cde8d30c..d138ddf72cec6 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/SignedCertificateTimestamp.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/SignedCertificateTimestamp.java @@ -1,7 +1,9 @@ package org.openqa.selenium.devtools.network.types; +import org.openqa.selenium.json.JsonInput; + /** - * Created by aohana + * Details of a signed certificate timestamp (SCT) */ public class SignedCertificateTimestamp { @@ -21,6 +23,22 @@ public class SignedCertificateTimestamp { private String signatureData; + public SignedCertificateTimestamp() { + } + + public SignedCertificateTimestamp(String status, String origin, String logDescription, + String logId, Double timestamp, String hashAlgorithm, + String signatureAlgorithm, String signatureData) { + this.status = status; + this.origin = origin; + this.logDescription = logDescription; + this.logId = logId; + this.timestamp = timestamp; + this.hashAlgorithm = hashAlgorithm; + this.signatureAlgorithm = signatureAlgorithm; + this.signatureData = signatureData; + } + /** Validation status. */ public String getStatus() { return status; @@ -100,4 +118,62 @@ public String getSignatureData() { public void setSignatureData(String signatureData) { this.signatureData = signatureData; } + + public static SignedCertificateTimestamp parseSignedCertificateTimestamp(JsonInput input) { + + String status = null; + + String origin = null; + + String logDescription = null; + + String logId = null; + + Number timestamp = null; + + String hashAlgorithm = null; + + String signatureAlgorithm = null; + + String signatureData = null; + + input.beginObject(); + + while (input.hasNext()) { + + switch (input.nextName()) { + case "status": + status = input.nextString(); + break; + case "origin": + origin = input.nextString(); + break; + case "logDescription": + logDescription = input.nextString(); + break; + case "logId": + logId = input.nextString(); + break; + case "timestamp": + timestamp = input.nextNumber(); + break; + case "hashAlgorithm": + hashAlgorithm = input.nextString(); + break; + case "signatureAlgorithm": + signatureAlgorithm = input.nextString(); + break; + case "signatureData": + signatureData = input.nextString(); + break; + default: + input.skipValue(); + break; + } + + } + + return new SignedCertificateTimestamp(status, origin, logDescription, logId, Double.valueOf(String.valueOf(timestamp)), hashAlgorithm, signatureAlgorithm, signatureData); + + } } diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeError.java b/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeError.java index 917b39837fc56..175302301b48e 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeError.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeError.java @@ -1,7 +1,9 @@ package org.openqa.selenium.devtools.network.types; +import org.openqa.selenium.json.JsonInput; + /** - * Created by aohana + * Information about a signed exchange response */ public class SignedExchangeError { @@ -40,4 +42,9 @@ public SignedExchangeErrorField getErrorField() { public void setErrorField(SignedExchangeErrorField errorField) { this.errorField = errorField; } + + public static SignedExchangeError parseResponse(JsonInput input) { + //TODO: @GED implement parser + return null; + } } diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeHeader.java b/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeHeader.java index 6a78557bd1b26..34bd22cf02d10 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeHeader.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeHeader.java @@ -1,10 +1,14 @@ package org.openqa.selenium.devtools.network.types; +import org.openqa.selenium.json.JsonInput; + +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; /** - * Created by aohana + * Information about a signed exchange header */ public class SignedExchangeHeader { @@ -18,6 +22,19 @@ public class SignedExchangeHeader { private List signatures; + public SignedExchangeHeader(String requestUrl, String requestMethod, Integer responseCode, + Map responseHeaders, + List signatures) { + this.requestUrl = requestUrl; + this.requestMethod = requestMethod; + this.responseCode = responseCode; + this.responseHeaders = responseHeaders; + this.signatures = signatures; + } + + public SignedExchangeHeader() { + } + /** Signed exchange request URL. */ public String getRequestUrl() { return requestUrl; @@ -67,4 +84,55 @@ public List getSignatures() { public void setSignatures(List signatures) { this.signatures = signatures; } + + public static SignedExchangeHeader parseResponse(JsonInput input) { + + String requestUrl = null; + + String requestMethod = null; + + Number responseCode = null; + + Map responseHeaders = null; + + List signatures = null; + + input.beginObject(); + + while (input.hasNext()) { + + switch (input.nextName()) { + case "requestUrl": + requestUrl = input.nextString(); + break; + case "requestMethod": + requestMethod = input.nextString(); + break; + case "responseCode": + responseCode = input.nextNumber(); + break; + case "responseHeaders": + input.beginObject(); + responseHeaders = new HashMap<>(); + while (input.hasNext()) { + responseHeaders.put(input.nextName(), input.nextString()); + } + break; + case "signatures": + input.beginArray(); + signatures = new ArrayList<>(); + while (input.hasNext()) { + signatures.add(SignedExchangeSignature.parseSignedExchangeSignature(input)); + } + input.endArray(); + break; + default: + input.skipValue(); + break; + } + + } + + return new SignedExchangeHeader(requestUrl, requestMethod, Integer.valueOf(String.valueOf(responseCode)), responseHeaders, signatures); + } } diff --git a/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeSignature.java b/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeSignature.java index 8ac7e2878e1b1..b01d1269aeb52 100644 --- a/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeSignature.java +++ b/java/client/src/org/openqa/selenium/devtools/network/types/SignedExchangeSignature.java @@ -1,9 +1,12 @@ package org.openqa.selenium.devtools.network.types; +import org.openqa.selenium.json.JsonInput; + +import java.util.ArrayList; import java.util.List; /** - * Created by aohana + * Information about a signed exchange signature */ public class SignedExchangeSignature { @@ -25,93 +28,214 @@ public class SignedExchangeSignature { private List certificates; - /** Signed exchange signature label. */ + public SignedExchangeSignature() { + } + + public SignedExchangeSignature(String label, String signature, String integrity, + String certUrl, String certSha256, String validityUrl, + Integer date, Integer expires, + List certificates) { + this.label = label; + this.signature = signature; + this.integrity = integrity; + this.certUrl = certUrl; + this.certSha256 = certSha256; + this.validityUrl = validityUrl; + this.date = date; + this.expires = expires; + this.certificates = certificates; + } + + /** + * Signed exchange signature label. + */ public String getLabel() { return label; } - /** Signed exchange signature label. */ + /** + * Signed exchange signature label. + */ public void setLabel(String label) { this.label = label; } - /** The hex string of signed exchange signature. */ + /** + * The hex string of signed exchange signature. + */ public String getSignature() { return signature; } - /** The hex string of signed exchange signature. */ + /** + * The hex string of signed exchange signature. + */ public void setSignature(String signature) { this.signature = signature; } - /** Signed exchange signature integrity. */ + /** + * Signed exchange signature integrity. + */ public String getIntegrity() { return integrity; } - /** Signed exchange signature integrity. */ + /** + * Signed exchange signature integrity. + */ public void setIntegrity(String integrity) { this.integrity = integrity; } - /** Signed exchange signature cert Url. */ + /** + * Signed exchange signature cert Url. + */ public String getCertUrl() { return certUrl; } - /** Signed exchange signature cert Url. */ + /** + * Signed exchange signature cert Url. + */ public void setCertUrl(String certUrl) { this.certUrl = certUrl; } - /** The hex string of signed exchange signature cert sha256. */ + /** + * The hex string of signed exchange signature cert sha256. + */ public String getCertSha256() { return certSha256; } - /** The hex string of signed exchange signature cert sha256. */ + /** + * The hex string of signed exchange signature cert sha256. + */ public void setCertSha256(String certSha256) { this.certSha256 = certSha256; } - /** Signed exchange signature validity Url. */ + /** + * Signed exchange signature validity Url. + */ public String getValidityUrl() { return validityUrl; } - /** Signed exchange signature validity Url. */ + /** + * Signed exchange signature validity Url. + */ public void setValidityUrl(String validityUrl) { this.validityUrl = validityUrl; } - /** Signed exchange signature date. */ + /** + * Signed exchange signature date. + */ public Integer getDate() { return date; } - /** Signed exchange signature date. */ + /** + * Signed exchange signature date. + */ public void setDate(Integer date) { this.date = date; } - /** Signed exchange signature expires. */ + /** + * Signed exchange signature expires. + */ public Integer getExpires() { return expires; } - /** Signed exchange signature expires. */ + /** + * Signed exchange signature expires. + */ public void setExpires(Integer expires) { this.expires = expires; } - /** The encoded certificates. */ + /** + * The encoded certificates. + */ public List getCertificates() { return certificates; } - /** The encoded certificates. */ + /** + * The encoded certificates. + */ public void setCertificates(List certificates) { this.certificates = certificates; } + + public static SignedExchangeSignature parseSignedExchangeSignature(JsonInput input) { + + String label = null; + + String signature = null; + + String integrity = null; + + String certUrl = null; + + String certSha256 = null; + + String validityUrl = null; + + Number date = null; + + Number expires = null; + + List certificates = null; + + input.beginObject(); + + while (input.hasNext()) { + + switch (input.nextName()) { + case "label": + label = input.nextString(); + break; + case "signature": + signature = input.nextString(); + break; + case "integrity": + integrity = input.nextString(); + break; + case "certUrl": + certUrl = input.nextString(); + break; + case "certSha256": + certSha256 = input.nextString(); + break; + case "validityUrl": + validityUrl = input.nextString(); + break; + case "date": + date = input.nextNumber(); + break; + case "expires": + expires = input.nextNumber(); + break; + case "certificates": + input.beginArray(); + certificates = new ArrayList<>(); + while (input.hasNext()) { + certificates.add(input.nextString()); + } + input.endArray(); + break; + default: + input.skipValue(); + break; + } + + } + + return new SignedExchangeSignature(label, signature, integrity, certUrl, certSha256, validityUrl, Integer.valueOf(String.valueOf(date)), Integer.valueOf(String.valueOf(expires)), certificates); + } } diff --git a/java/client/test/org/openqa/selenium/devtools/DevToolsNetworkTest.java b/java/client/test/org/openqa/selenium/devtools/DevToolsNetworkTest.java index e8e41c369ceca..abcd0253b92e2 100644 --- a/java/client/test/org/openqa/selenium/devtools/DevToolsNetworkTest.java +++ b/java/client/test/org/openqa/selenium/devtools/DevToolsNetworkTest.java @@ -129,4 +129,6 @@ public void testGetRequestPostData(){ chromeDriver.get(TEST_WEB_SITE_ADDRESS); } + //TODO: @GED add test cases + }