-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extension Signing request endpoint #982
Merged
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
a9e8973
feat!: Generic signing extension handler
usmansaleem e4bf550
cq: Remove unnecessary LOG variable
usmansaleem 91cfe43
feat: Use base64 encoding of payload in response
usmansaleem 03ced53
tests - Add acceptance tests
usmansaleem 2e99ece
changelog
usmansaleem b3d5707
fix: Use specific body for extension signing
usmansaleem c12c749
test: Update Acceptance tests
usmansaleem 12e5b40
Update cli option
usmansaleem 423e042
Deleting Eth1 AT
usmansaleem ee024bc
Refactor signing data to use header.payload.sig format
usmansaleem 8d08221
Refactor signing extension to eth2 mode. Fix acceptance test
usmansaleem 87ea174
spotless fix
usmansaleem d413431
Merge remote-tracking branch 'upstream/master' into sign_extension
usmansaleem 4cd29c6
changelog
usmansaleem 9422720
changing json response format
usmansaleem bf3dada
Merge remote-tracking branch 'upstream/master' into sign_extension
usmansaleem a1fea94
Merge remote-tracking branch 'upstream/master' into sign_extension
usmansaleem 5a2903f
fix: Update bouncycastle libraries
usmansaleem f7cb63e
fix: Update transitive dependency threetenbp and google cloud secretm…
usmansaleem 0c11f44
build: assign dependency scan nvd api key from env variable
usmansaleem 9aa7ecc
changelog
usmansaleem 11c1dd6
fix: Update guava and commons-logging libraries
usmansaleem 458975c
Merge branch 'vuln_scan_fix' into sign_extension
usmansaleem 23984b2
fix: Update response to return hex encoded signature
usmansaleem 7f06899
Merge remote-tracking branch 'upstream/master' into sign_extension
usmansaleem 17692cf
Enforce strict fields parsing for SigningExtensionHandler
usmansaleem 3c60ee6
Send Base64 encoded payload in the response
usmansaleem e58d150
Use appropriate type for tinestamp
usmansaleem c4fe46f
Merge remote-tracking branch 'upstream/master' into sign_extension
usmansaleem 6cbae83
Merge remote-tracking branch 'upstream/master' into sign_extension
usmansaleem 38a6db7
fix: Always use application/json as Content-Type header
usmansaleem a6eb923
build - debug information in docker test.sh
usmansaleem acf0714
build - fix docker goss test
usmansaleem e11ae2b
build - store docker dgoss test results
usmansaleem File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
187 changes: 187 additions & 0 deletions
187
...java/tech/pegasys/web3signer/tests/signing/ProofOfValidationSigningExtAcceptanceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* | ||
* Copyright 2024 ConsenSys AG. | ||
* | ||
* 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 tech.pegasys.web3signer.tests.signing; | ||
|
||
import static io.restassured.http.ContentType.JSON; | ||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static tech.pegasys.teku.spec.SpecMilestone.DENEB; | ||
|
||
import tech.pegasys.teku.bls.BLS; | ||
import tech.pegasys.teku.bls.BLSKeyPair; | ||
import tech.pegasys.teku.bls.BLSPublicKey; | ||
import tech.pegasys.teku.bls.BLSSecretKey; | ||
import tech.pegasys.teku.bls.BLSSignature; | ||
import tech.pegasys.teku.spec.networks.Eth2Network; | ||
import tech.pegasys.web3signer.core.service.http.SigningObjectMapperFactory; | ||
import tech.pegasys.web3signer.core.service.http.handlers.signing.ProofOfValidationBody; | ||
import tech.pegasys.web3signer.core.service.http.handlers.signing.SigningExtensionType; | ||
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder; | ||
import tech.pegasys.web3signer.dsl.utils.MetadataFileHelpers; | ||
import tech.pegasys.web3signer.signing.KeyType; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Path; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import io.restassured.http.ContentType; | ||
import org.apache.tuweni.bytes.Bytes; | ||
import org.apache.tuweni.bytes.Bytes32; | ||
import org.apache.tuweni.units.bigints.UInt64; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.EnumSource; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
|
||
public class ProofOfValidationSigningExtAcceptanceTest extends SigningAcceptanceTestBase { | ||
|
||
private static final String PRIVATE_KEY = | ||
"3ee2224386c82ffea477e2adf28a2929f5c349165a4196158c7f3a2ecca40f35"; | ||
private static final MetadataFileHelpers METADATA_FILE_HELPERS = new MetadataFileHelpers(); | ||
private static final BLSSecretKey KEY = | ||
BLSSecretKey.fromBytes(Bytes32.fromHexString(PRIVATE_KEY)); | ||
private static final BLSKeyPair KEY_PAIR = new BLSKeyPair(KEY); | ||
private static final BLSPublicKey PUBLIC_KEY = KEY_PAIR.getPublicKey(); | ||
private static final ObjectMapper JSON_MAPPER = SigningObjectMapperFactory.createObjectMapper(); | ||
|
||
@BeforeEach | ||
void setup() { | ||
final String configFilename = PUBLIC_KEY.toString().substring(2); | ||
final Path keyConfigFile = testDirectory.resolve(configFilename + ".yaml"); | ||
METADATA_FILE_HELPERS.createUnencryptedYamlFileAt(keyConfigFile, PRIVATE_KEY, KeyType.BLS); | ||
|
||
setForkEpochsAndStartSigner( | ||
new SignerConfigurationBuilder() | ||
.withKeyStoreDirectory(testDirectory) | ||
.withMode("eth2") | ||
.withNetwork(Eth2Network.MINIMAL.configName()) | ||
.withSigningExtEnabled(true), | ||
DENEB); | ||
} | ||
|
||
@ParameterizedTest(name = "{index} - Testing Accept Media Type: {0}") | ||
@EnumSource( | ||
value = ContentType.class, | ||
names = {"ANY", "JSON", "TEXT"}) | ||
void extensionSigningData(final ContentType acceptMediaType) throws Exception { | ||
final var signingExtensionBody = | ||
new ProofOfValidationBody( | ||
SigningExtensionType.PROOF_OF_VALIDATION, | ||
"AT", | ||
UInt64.valueOf(System.currentTimeMillis())); | ||
final var payload = JSON_MAPPER.writeValueAsString(signingExtensionBody); | ||
|
||
final var response = | ||
signer.signExtensionPayload(PUBLIC_KEY.toString(), payload, acceptMediaType); | ||
|
||
response.then().statusCode(200).contentType(JSON); | ||
|
||
final var signatureResponse = | ||
JSON_MAPPER.readValue(response.asByteArray(), ProofOfValidationResponse.class); | ||
|
||
// assert that the signature is valid | ||
final var blsSignature = | ||
BLSSignature.fromBytesCompressed(Bytes.fromHexString(signatureResponse.signature)); | ||
|
||
final var isValidBLSSig = | ||
BLS.verify(PUBLIC_KEY, Bytes.wrap(payload.getBytes(UTF_8)), blsSignature); | ||
assertThat(isValidBLSSig).isTrue(); | ||
|
||
// assert that Base64 encoded payload is correct | ||
assertThat(signatureResponse.payload) | ||
.isEqualTo(Bytes.wrap(payload.getBytes(UTF_8)).toBase64String()); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = {"1634025600000", "\"1634025600000\""}) | ||
void timestampAsStringAndNumberResultsInValidSignature(final String timestampValue) | ||
throws IOException { | ||
final var payloadFormat = | ||
""" | ||
{ | ||
"type": "PROOF_OF_VALIDATION", | ||
"platform": "AT", | ||
"timestamp": %s | ||
} | ||
"""; | ||
final var payload = String.format(payloadFormat, timestampValue); | ||
|
||
final var response = signer.signExtensionPayload(PUBLIC_KEY.toString(), payload, JSON); | ||
response.then().statusCode(200).contentType(JSON); | ||
|
||
final var signatureResponse = | ||
JSON_MAPPER.readValue(response.asByteArray(), ProofOfValidationResponse.class); | ||
|
||
// assert that the signature is valid | ||
final var blsSignature = | ||
BLSSignature.fromBytesCompressed(Bytes.fromHexString(signatureResponse.signature)); | ||
|
||
final var isValidBLSSig = | ||
BLS.verify(PUBLIC_KEY, Bytes.wrap(payload.getBytes(UTF_8)), blsSignature); | ||
assertThat(isValidBLSSig).isTrue(); | ||
|
||
// assert that Base64 encoded payload is correct | ||
assertThat(signatureResponse.payload) | ||
.isEqualTo(Bytes.wrap(payload.getBytes(UTF_8)).toBase64String()); | ||
} | ||
|
||
@Test | ||
void invalidIdentifierCausesNotFound() throws Exception { | ||
final ProofOfValidationBody proofOfValidationBody = | ||
new ProofOfValidationBody( | ||
SigningExtensionType.PROOF_OF_VALIDATION, | ||
"AT", | ||
UInt64.valueOf(System.currentTimeMillis())); | ||
final String data = JSON_MAPPER.writeValueAsString(proofOfValidationBody); | ||
|
||
signer.signExtensionPayload("0x1234", data, JSON).then().statusCode(404); | ||
} | ||
|
||
@ParameterizedTest(name = "{index} - Testing Invalid Body: {0}") | ||
@ValueSource(strings = {"", "invalid", "{}", "{\"data\": \"invalid\"}"}) | ||
void invalidBodyCausesBadRequestStatusCode(final String data) { | ||
signer.signExtensionPayload(PUBLIC_KEY.toString(), data, JSON).then().statusCode(400); | ||
} | ||
|
||
@Test | ||
void invalidSignExtensionTypeCausesBadRequestStatusCode() throws Exception { | ||
final ProofOfValidationBody proofOfValidationBody = | ||
new ProofOfValidationBody( | ||
SigningExtensionType.PROOF_OF_VALIDATION, | ||
"AT", | ||
UInt64.valueOf(System.currentTimeMillis())); | ||
var payload = JSON_MAPPER.writeValueAsString(proofOfValidationBody); | ||
payload = payload.replace("PROOF_OF_VALIDATION", "INVALID_TYPE"); | ||
|
||
signer.signExtensionPayload(PUBLIC_KEY.toString(), payload, JSON).then().statusCode(400); | ||
} | ||
|
||
@Test | ||
void extraJsonFieldsCausesBadRequestStatusCode() throws Exception { | ||
final ProofOfValidationBody proofOfValidationBody = | ||
new ProofOfValidationBody( | ||
SigningExtensionType.PROOF_OF_VALIDATION, | ||
"AT", | ||
UInt64.valueOf(System.currentTimeMillis())); | ||
var payload = JSON_MAPPER.writeValueAsString(proofOfValidationBody); | ||
payload = payload.replace("}", ",\"extraField\": \"extraValue\"}"); | ||
|
||
signer.signExtensionPayload(PUBLIC_KEY.toString(), payload, JSON).then().statusCode(400); | ||
} | ||
|
||
record ProofOfValidationResponse( | ||
@JsonProperty(value = "payload", required = true) String payload, | ||
@JsonProperty(value = "signature", required = true) String signature) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonder if we should put this under a web3signer-specific namespace? e.g.
/w3s/v1/eth2/sign
,/w3s/v1/sign
or/v1/eth2/w3s/sign
.There's precedent in teku for spec vs teku-specific https://consensys.github.io/teku/#tag/Teku and I think there's some merit for web3signer to follow that pattern.
Other CLs too: https://lighthouse-book.sigmaprime.io/api-lighthouse.html