Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into blobsidecar_sign
Browse files Browse the repository at this point in the history
  • Loading branch information
usmansaleem committed Aug 29, 2023
2 parents 91fa00a + 73a5741 commit fe2c707
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

### Features Added
- Signing support for BlobSidecar and BlindedBlobSidecar in Deneb fork.
- Add `--azure-response-timeout` to allow request response timeout to be configurable, the field `timeout` is also accepted in the Azure metadata file. [#888](https://github.com/Consensys/web3signer/pull/888)

## 23.8.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public abstract class PicoCliAzureKeyVaultParameters implements AzureKeyVaultPar
paramLabel = "<CLIENT_SECRET>")
private String clientSecret;

@Option(
names = {"--azure-response-timeout"},
description = "The response timeout to be used by the http client (in seconds)",
paramLabel = "<AZURE_RESPONSE_TIMEOUT>")
private long timeout = 60;

@Override
public boolean isAzureKeyVaultEnabled() {
return azureKeyVaultEnabled;
Expand Down Expand Up @@ -90,4 +96,9 @@ public String getClientId() {
public String getClientSecret() {
return clientSecret;
}

@Override
public long getTimeout() {
return timeout;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ private MappedResults<ArtifactSigner> bulkLoadSigners(
azureKeyVaultConfig.getClientSecret(),
azureKeyVaultConfig.getKeyVaultName(),
azureKeyVaultConfig.getTenantId(),
azureKeyVaultConfig.getAuthenticationMode());
azureKeyVaultConfig.getAuthenticationMode(),
azureKeyVaultConfig.getTimeout());
final SecpAzureBulkLoader secpAzureBulkLoader =
new SecpAzureBulkLoader(azureKeyVault, azureSignerFactory);
final MappedResults<ArtifactSigner> azureResult =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.net.URI;
import java.net.http.HttpRequest;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -31,7 +32,9 @@
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
import com.azure.core.exception.ResourceNotFoundException;
import com.azure.core.http.HttpClient;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.util.HttpClientOptions;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.security.keyvault.keys.KeyClient;
Expand Down Expand Up @@ -68,33 +71,48 @@ public static AzureKeyVault createUsingClientSecretCredentials(
final String clientSecret,
final String tenantId,
final String vaultName,
final ExecutorService executorService) {
final ExecutorService executorService,
final long timeout) {
final TokenCredential tokenCredential =
new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
.executorService(executorService)
.build();
return new AzureKeyVault(tokenCredential, vaultName);
return new AzureKeyVault(tokenCredential, vaultName, timeout);
}

public static AzureKeyVault createUsingManagedIdentity(
final Optional<String> clientId, final String vaultName) {
final Optional<String> clientId, final String vaultName, final long timeout) {
final ManagedIdentityCredentialBuilder managedIdentityCredentialBuilder =
new ManagedIdentityCredentialBuilder();
clientId.ifPresent(managedIdentityCredentialBuilder::clientId);
return new AzureKeyVault(managedIdentityCredentialBuilder.build(), vaultName);
return new AzureKeyVault(managedIdentityCredentialBuilder.build(), vaultName, timeout);
}

private AzureKeyVault(final TokenCredential tokenCredential, final String vaultName) {
private AzureKeyVault(
final TokenCredential tokenCredential, final String vaultName, final long timeout) {
this.tokenCredential = tokenCredential;
final String vaultUrl = constructAzureKeyVaultUrl(vaultName);

secretClient =
new SecretClientBuilder().vaultUrl(vaultUrl).credential(tokenCredential).buildClient();
final HttpClient customisedHttpClient =
HttpClient.createDefault(
new HttpClientOptions().setResponseTimeout(Duration.ofSeconds(timeout)));

keyClient = new KeyClientBuilder().vaultUrl(vaultUrl).credential(tokenCredential).buildClient();
secretClient =
new SecretClientBuilder()
.httpClient(customisedHttpClient)
.vaultUrl(vaultUrl)
.credential(tokenCredential)
.buildClient();

keyClient =
new KeyClientBuilder()
.httpClient(customisedHttpClient)
.vaultUrl(vaultUrl)
.credential(tokenCredential)
.buildClient();
}

public Optional<String> fetchSecret(final String secretName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class AzureKeyVaultTest {
private static final String EXPECTED_KEY2 =
"0x5aba5b89c1d8b731dba1ba29128a4070df0dbfd7e0a67edb40ae7f860cd3ca1c";
private final ExecutorService azureExecutor = Executors.newCachedThreadPool();
private final long AZURE_DEFAULT_TIMEOUT = 60;

@BeforeAll
public static void setup() {
Expand All @@ -58,7 +59,7 @@ public static void setup() {
void fetchExistingSecretKeyFromAzureVault() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);
final Optional<String> hexKey = azureKeyVault.fetchSecret(SECRET_NAME);
Assertions.assertThat(hexKey).isNotEmpty().get().isEqualTo(EXPECTED_KEY);
}
Expand All @@ -67,7 +68,7 @@ void fetchExistingSecretKeyFromAzureVault() {
void connectingWithInvalidClientSecretThrowsException() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, "invalid", TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, "invalid", TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);
Assertions.assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> azureKeyVault.fetchSecret(SECRET_NAME))
.withMessageContaining("Invalid client secret");
Expand All @@ -77,7 +78,7 @@ void connectingWithInvalidClientSecretThrowsException() {
void connectingWithInvalidClientIdThrowsException() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
"invalid", CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
"invalid", CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);
Assertions.assertThatExceptionOfType(RuntimeException.class)
.isThrownBy(() -> azureKeyVault.fetchSecret(SECRET_NAME))
.withMessageContaining(
Expand All @@ -88,15 +89,15 @@ void connectingWithInvalidClientIdThrowsException() {
void nonExistingSecretReturnEmpty() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);
assertThat(azureKeyVault.fetchSecret("X-" + SECRET_NAME)).isEmpty();
}

@Test
void secretsCanBeMappedUsingCustomMappingFunction() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<SimpleEntry<String, String>> result =
azureKeyVault.mapSecrets(SimpleEntry::new, Collections.emptyMap());
Expand All @@ -113,7 +114,7 @@ void secretsCanBeMappedUsingCustomMappingFunction() {
void keyPropertiesCanBeMappedUsingCustomMappingFunction() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<String> result =
azureKeyVault.mapKeyProperties(KeyProperties::getName, Collections.emptyMap());
Expand All @@ -128,7 +129,7 @@ void keyPropertiesCanBeMappedUsingCustomMappingFunction() {
void mapSecretsUsingTags() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<SimpleEntry<String, String>> result =
azureKeyVault.mapSecrets(SimpleEntry::new, Map.of("ENV", "TEST"));
Expand All @@ -150,7 +151,7 @@ void mapSecretsUsingTags() {
void mapKeyPropertiesUsingTags() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<String> result =
azureKeyVault.mapKeyProperties(KeyProperties::getName, Map.of("ENV", "TEST"));
Expand All @@ -165,7 +166,7 @@ void mapKeyPropertiesUsingTags() {
void mapSecretsWhenTagsDoesNotExist() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<SimpleEntry<String, String>> result =
azureKeyVault.mapSecrets(SimpleEntry::new, Map.of("INVALID_TAG", "INVALID_TEST"));
Expand All @@ -181,7 +182,7 @@ void mapSecretsWhenTagsDoesNotExist() {
void mapKeyPropertiesWhenTagsDoesNotExist() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<String> result =
azureKeyVault.mapKeyProperties(
Expand All @@ -198,7 +199,7 @@ void mapKeyPropertiesWhenTagsDoesNotExist() {
void mapSecretsThrowsAwayObjectsWhichFailMapper() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<SimpleEntry<String, String>> result =
azureKeyVault.mapSecrets(
Expand Down Expand Up @@ -226,7 +227,7 @@ void mapSecretsThrowsAwayObjectsWhichFailMapper() {
void mapKeyPropertiesThrowsAwayObjectsWhichFailMapper() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<String> result =
azureKeyVault.mapKeyProperties(
Expand Down Expand Up @@ -255,7 +256,7 @@ void mapKeyPropertiesThrowsAwayObjectsWhichFailMapper() {
void mapSecretsThrowsAwayObjectsWhichMapToNull() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<SimpleEntry<String, String>> result =
azureKeyVault.mapSecrets(
Expand All @@ -282,7 +283,7 @@ void mapSecretsThrowsAwayObjectsWhichMapToNull() {
void mapKeyPropertiesThrowsAwayObjectsWhichMapToNull() {
final AzureKeyVault azureKeyVault =
createUsingClientSecretCredentials(
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor);
CLIENT_ID, CLIENT_SECRET, TENANT_ID, VAULT_NAME, azureExecutor, AZURE_DEFAULT_TIMEOUT);

final MappedResults<String> result =
azureKeyVault.mapKeyProperties(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ private EthSecpArtifactSigner createSigner(
keyName,
azureKeyVaultParameters.getClientId(),
azureKeyVaultParameters.getClientSecret(),
azureKeyVaultParameters.getTenantId())));
azureKeyVaultParameters.getTenantId(),
azureKeyVaultParameters.getTimeout())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,32 @@ public AzureKeyVault createAzureKeyVault(final AzureKeyVaultParameters azureKeyV
azureKeyVaultParameters.getClientSecret(),
azureKeyVaultParameters.getKeyVaultName(),
azureKeyVaultParameters.getTenantId(),
azureKeyVaultParameters.getAuthenticationMode());
azureKeyVaultParameters.getAuthenticationMode(),
azureKeyVaultParameters.getTimeout());
}

public AzureKeyVault createAzureKeyVault(
final String clientId,
final String clientSecret,
final String keyVaultName,
final String tenantId,
final AzureAuthenticationMode mode) {
final AzureAuthenticationMode mode,
final long httpClientTimeout) {
switch (mode) {
case USER_ASSIGNED_MANAGED_IDENTITY:
return AzureKeyVault.createUsingManagedIdentity(Optional.of(clientId), keyVaultName);
return AzureKeyVault.createUsingManagedIdentity(
Optional.of(clientId), keyVaultName, httpClientTimeout);
case SYSTEM_ASSIGNED_MANAGED_IDENTITY:
return AzureKeyVault.createUsingManagedIdentity(Optional.empty(), keyVaultName);
return AzureKeyVault.createUsingManagedIdentity(
Optional.empty(), keyVaultName, httpClientTimeout);
default:
return AzureKeyVault.createUsingClientSecretCredentials(
clientId, clientSecret, tenantId, keyVaultName, getOrCreateExecutor());
clientId,
clientSecret,
tenantId,
keyVaultName,
getOrCreateExecutor(),
httpClientTimeout);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ public interface AzureKeyVaultParameters {
String getClientSecret();

Map<String, String> getTags();

long getTimeout();
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class AzureKeySigningMetadata extends SigningMetadata {
private final String tenantId;
private final String vaultName;
private final String keyName;
private final long timeout;

@JsonCreator
public AzureKeySigningMetadata(
Expand All @@ -33,13 +34,15 @@ public AzureKeySigningMetadata(
@JsonProperty("tenantId") final String tenantId,
@JsonProperty("vaultName") final String vaultName,
@JsonProperty("keyName") final String keyName,
@JsonProperty(value = "keyType") final KeyType keyType) {
@JsonProperty(value = "keyType") final KeyType keyType,
@JsonProperty(value = "timeout") final long timeout) {
super(TYPE, keyType != null ? keyType : KeyType.SECP256K1);
this.clientId = clientId;
this.clientSecret = clientSecret;
this.tenantId = tenantId;
this.vaultName = vaultName;
this.keyName = keyName;
this.timeout = (timeout != 0) ? timeout : 60;
}

public String getClientId() {
Expand All @@ -62,6 +65,10 @@ public String getKeyName() {
return keyName;
}

public long getTimeout() {
return timeout;
}

@Override
public ArtifactSigner createSigner(final ArtifactSignerFactory artifactSignerFactory) {
return artifactSignerFactory.create(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class AzureSecretSigningMetadata extends SigningMetadata implements Azure
private final String vaultName;
private final String secretName;
private final AzureAuthenticationMode authenticationMode;
private final long timeout;

public AzureSecretSigningMetadata(
final String clientId,
Expand All @@ -39,7 +40,8 @@ public AzureSecretSigningMetadata(
final String vaultName,
final String secretName,
final AzureAuthenticationMode azureAuthenticationMode,
final KeyType keyType) {
final KeyType keyType,
final long timeout) {
super(TYPE, keyType != null ? keyType : KeyType.BLS);
this.clientId = clientId;
this.clientSecret = clientSecret;
Expand All @@ -50,6 +52,7 @@ public AzureSecretSigningMetadata(
azureAuthenticationMode == null
? AzureAuthenticationMode.CLIENT_SECRET
: azureAuthenticationMode;
this.timeout = timeout;
}

@Override
Expand Down Expand Up @@ -97,4 +100,9 @@ public Map<String, String> getTags() {
// user is already providing the secret name to load the secret from.
return Collections.emptyMap();
}

@Override
public long getTimeout() {
return timeout;
}
}
Loading

0 comments on commit fe2c707

Please sign in to comment.