Skip to content
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

[Key Vault] Add public_exponent option to create_key #18024

Merged
merged 4 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/pipelines/templates/jobs/live.tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
Location: ${{ coalesce(parameters.Location, parameters.CloudConfig.Location) }}
ServiceDirectory: '${{ parameters.ServiceDirectory }}'
SubscriptionConfiguration: ${{ parameters.CloudConfig.SubscriptionConfiguration }}
ArmTemplateParameters: ${{ coalesce(parameters.CloudConfig.ArmTemplateParameters, '@{}') }}
ArmTemplateParameters: $(ArmTemplateParameters)

- template: ../steps/build-test.yml
parameters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def create_key(self, name, key_type, **kwargs):
:keyword curve: Elliptic curve name. Applies only to elliptic curve keys. Defaults to the NIST P-256
elliptic curve. To create an elliptic curve key, consider using :func:`create_ec_key` instead.
:paramtype curve: ~azure.keyvault.keys.KeyCurveName or str
:keyword int public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM.
:keyword key_operations: Allowed key operations
:paramtype key_operations: list[~azure.keyvault.keys.KeyOperation or str]
:keyword bool enabled: Whether the key is enabled for use.
Expand Down Expand Up @@ -93,7 +94,8 @@ def create_key(self, name, key_type, **kwargs):
key_attributes=attributes,
key_ops=kwargs.pop("key_operations", None),
tags=kwargs.pop("tags", None),
curve=kwargs.pop("curve", None)
curve=kwargs.pop("curve", None),
public_exponent=kwargs.pop("public_exponent", None)
)

bundle = self._client.create_key(
Expand All @@ -114,6 +116,7 @@ def create_rsa_key(self, name, **kwargs):

:param str name: The name for the new key.
:keyword int size: Key size in bits, for example 2048, 3072, or 4096.
:keyword int public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM.
:keyword bool hardware_protected: Whether the key should be created in a hardware security module.
Defaults to ``False``.
:keyword key_operations: Allowed key operations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ async def create_key(self, name: str, key_type: "Union[str, KeyType]", **kwargs:
:keyword curve: Elliptic curve name. Applies only to elliptic curve keys. Defaults to the NIST P-256
elliptic curve. To create an elliptic curve key, consider using :func:`create_ec_key` instead.
:paramtype curve: ~azure.keyvault.keys.KeyCurveName or str
:keyword int public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should document this on create_rsa_key as well, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should! I remember making that update in a dream last night, but I evidently didn't remember to translate that into the material world

:keyword key_operations: Allowed key operations
:paramtype key_operations: list[~azure.keyvault.keys.KeyOperation or str]
:keyword bool enabled: Whether the key is enabled for use.
Expand Down Expand Up @@ -92,7 +93,8 @@ async def create_key(self, name: str, key_type: "Union[str, KeyType]", **kwargs:
key_attributes=attributes,
key_ops=kwargs.pop("key_operations", None),
tags=kwargs.pop("tags", None),
curve=kwargs.pop("curve", None)
curve=kwargs.pop("curve", None),
public_exponent=kwargs.pop("public_exponent", None)
)

bundle = await self._client.create_key(
Expand All @@ -112,6 +114,7 @@ async def create_rsa_key(self, name: str, **kwargs: "Any") -> KeyVaultKey:

:param str name: The name for the new key.
:keyword int size: Key size in bits, for example 2048, 3072, or 4096.
:keyword int public_exponent: The RSA public exponent to use. Applies only to RSA keys created in a Managed HSM.
:keyword bool hardware_protected: Whether the key should be created in a hardware security module.
Defaults to ``False``.
:keyword key_operations: Allowed key operations
Expand Down
10 changes: 5 additions & 5 deletions sdk/keyvault/azure-keyvault-keys/platform-matrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"include": [
{
"Agent": {
"ubuntu-18.04": {
"OSVmImage": "MMSUbuntu18.04",
"Pool": "azsdk-pool-mms-ubuntu-1804-general",
"ArmTemplateParameters": "@{ enableHsm = $true }"
}
"ubuntu-18.04_ManagedHSM": {
"OSVmImage": "MMSUbuntu18.04",
"Pool": "azsdk-pool-mms-ubuntu-1804-general",
"ArmTemplateParameters": "@{ enableHsm = $true }"
}
},
"PythonVersion": "3.9",
"CoverageArg": ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '0'
Content-Type:
- application/json
User-Agent:
- azsdk-python-keyvault-keys/4.4.0b5 Python/3.5.3 (Windows-10-10.0.19041-SP0)
method: POST
uri: https://managedhsmname.managedhsm.azure.net/keys/livekvtestrsa-keyaa84129c/create?api-version=7.2-preview
response:
body:
string: ''
headers:
cache-control:
- no-cache
content-length:
- '0'
content-security-policy:
- default-src 'self'
content-type:
- application/json; charset=utf-8
strict-transport-security:
- max-age=31536000; includeSubDomains
www-authenticate:
- Bearer authorization="https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47",
resource="https://managedhsm.azure.net"
x-content-type-options:
- nosniff
x-frame-options:
- SAMEORIGIN
x-ms-server-latency:
- '1'
status:
code: 401
message: Unauthorized
- request:
body: '{"public_exponent": 17, "kty": "RSA-HSM"}'
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '41'
Content-Type:
- application/json
User-Agent:
- azsdk-python-keyvault-keys/4.4.0b5 Python/3.5.3 (Windows-10-10.0.19041-SP0)
method: POST
uri: https://managedhsmname.managedhsm.azure.net/keys/livekvtestrsa-keyaa84129c/create?api-version=7.2-preview
response:
body:
string: '{"attributes":{"created":1618353119,"enabled":true,"exportable":false,"recoverableDays":90,"recoveryLevel":"Recoverable+Purgeable","updated":1618353119},"key":{"e":"EQ","key_ops":["wrapKey","decrypt","encrypt","unwrapKey","sign","verify"],"kid":"https://managedhsmname.managedhsm.azure.net/keys/livekvtestrsa-keyaa84129c/a63a1a240ff003079a3a50fb3116302b","kty":"RSA-HSM","n":"nO6rF2ru8HUAHbf2VyzVge6ic77k_Ju2VGuMKhNaX4nac8S2jMfHOYfkCmNi_NuZ_RUSYEkjtwwwh5LkAKwGP6AjKkEESbZiOyeBPi5bJB5A9g0-JKDT1Yudpnl4nBoXZinhvj0Dgr0LS38r-vu6wJjt_w_37Ofiun_sFCJcLGUfqN6KSGBbAE4XscLOY3GRUl1E3Mcq232R4yRxWsEhGmMDOVEM5VocRUiZOD-LRc0QclHQYX1lwto93UX272VVx5BrRTAtf9XZdTnWajk7xM-JXlYkkhon5KmdTavFL0pMGv23mnSjIMFT5sUPXanEYkwM1RqSJWnIRt2YoyVCzQ"}}'
headers:
cache-control:
- no-cache
content-length:
- '722'
content-security-policy:
- default-src 'self'
content-type:
- application/json; charset=utf-8
strict-transport-security:
- max-age=31536000; includeSubDomains
x-content-type-options:
- nosniff
x-frame-options:
- SAMEORIGIN
x-ms-keyvault-network-info:
- conn_type=Ipv4;addr=172.92.159.124;act_addr_fam=Ipv4;
x-ms-keyvault-region:
- eastus2
x-ms-server-latency:
- '1041'
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Content-Length:
- '0'
Content-Type:
- application/json
User-Agent:
- azsdk-python-keyvault-keys/4.4.0b5 Python/3.5.3 (Windows-10-10.0.19041-SP0)
method: POST
uri: https://managedhsmname.managedhsm.azure.net/keys/livekvtestrsa-keyad3012ae/create?api-version=7.2-preview
response:
body:
string: ''
headers:
cache-control: no-cache
content-length: '0'
content-security-policy: default-src 'self'
content-type: application/json; charset=utf-8
strict-transport-security: max-age=31536000; includeSubDomains
www-authenticate: Bearer authorization="https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47",
resource="https://managedhsm.azure.net"
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-ms-server-latency: '1'
status:
code: 401
message: Unauthorized
url: https://mcpatinotesthsm.managedhsm.azure.net/keys/livekvtestrsa-keyad3012ae/create?api-version=7.2-preview
- request:
body: '{"public_exponent": 17, "kty": "RSA-HSM"}'
headers:
Accept:
- application/json
Content-Length:
- '41'
Content-Type:
- application/json
User-Agent:
- azsdk-python-keyvault-keys/4.4.0b5 Python/3.5.3 (Windows-10-10.0.19041-SP0)
method: POST
uri: https://managedhsmname.managedhsm.azure.net/keys/livekvtestrsa-keyad3012ae/create?api-version=7.2-preview
response:
body:
string: '{"attributes":{"created":1618353643,"enabled":true,"exportable":false,"recoverableDays":90,"recoveryLevel":"Recoverable+Purgeable","updated":1618353643},"key":{"e":"EQ","key_ops":["wrapKey","decrypt","encrypt","unwrapKey","sign","verify"],"kid":"https://managedhsmname.managedhsm.azure.net/keys/livekvtestrsa-keyad3012ae/d0b837d03f9c069780c5d37fd8bce435","kty":"RSA-HSM","n":"nIkUlKQZuvk31cPRCAzYoHZ-lHpSBUHLfSPQsPpyy5LpUrJPHFozMNUAZ2VUKR_-9S17Znn5CVwbAKXfXPx-5dsq6_hqjvfMtwoWJDU4tPa5vqS-SxZQ-CTYj8N4N1rx2qyF5Z18OSwZGQ3up7vl8RsPSeI1SEIhHWPIg6A4VLe0VhByiYXyOIZeDm7MVnpeisQMgaQoiObgYYzN5xBpbGSFd2_7H-AivK58BgRGoAzfd_FXVS1a9244hHH3gFy7oSo3ccPZyI_kKjXlB4kTmvvZBdQeVbWOeaNDemxsH8TsJy1yR9V1lwkZ08M19iYYbYtomeLpAcws46kPWc-wjQ"}}'
headers:
cache-control: no-cache
content-length: '722'
content-security-policy: default-src 'self'
content-type: application/json; charset=utf-8
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-ms-keyvault-network-info: conn_type=Ipv4;addr=172.92.159.124;act_addr_fam=Ipv4;
x-ms-keyvault-region: eastus2
x-ms-server-latency: '812'
status:
code: 200
message: OK
url: https://mcpatinotesthsm.managedhsm.azure.net/keys/livekvtestrsa-keyad3012ae/create?api-version=7.2-preview
version: 1
16 changes: 15 additions & 1 deletion sdk/keyvault/azure-keyvault-keys/tests/test_key_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

from azure.core.exceptions import ResourceExistsError, ResourceNotFoundError
from azure.core.pipeline.policies import SansIOHTTPPolicy
from azure.keyvault.keys import JsonWebKey, KeyClient, KeyCurveName
from azure.keyvault.keys import JsonWebKey, KeyClient
from parameterized import parameterized, param
from six import byte2int

from _shared.test_case import KeyVaultTestCase
from _test_case import KeysTestCase, suffixed_test_name
Expand Down Expand Up @@ -196,6 +197,19 @@ def test_key_crud_operations(self, **kwargs):
self.assertIsNotNone(deleted_key)
self.assertEqual(rsa_key.id, deleted_key.id)

def test_rsa_public_exponent_mhsm(self, **kwargs):
"""The public exponent of a Managed HSM RSA key can be specified during creation"""
self._skip_if_not_configured(True)
endpoint_url = self.managed_hsm_url

client = self.create_key_client(endpoint_url)
self.assertIsNotNone(client)

key_name = self.get_resource_name("rsa-key")
key = self._create_rsa_key(client, key_name, hardware_protected=True, public_exponent=17)
public_exponent = byte2int(key.key.e)
assert public_exponent == 17

@parameterized.expand([param(is_hsm=b) for b in [True, False]], name_func=suffixed_test_name)
def test_backup_restore(self, **kwargs):
is_hsm = kwargs.pop("is_hsm")
Expand Down
17 changes: 16 additions & 1 deletion sdk/keyvault/azure-keyvault-keys/tests/test_keys_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

from azure.core.exceptions import ResourceExistsError, ResourceNotFoundError
from azure.core.pipeline.policies import SansIOHTTPPolicy
from azure.keyvault.keys import JsonWebKey, KeyCurveName
from azure.keyvault.keys import JsonWebKey
from azure.keyvault.keys.aio import KeyClient
from devtools_testutils import PowerShellPreparer
from parameterized import parameterized, param
from six import byte2int

from _shared.test_case_async import KeyVaultTestCase
from _test_case import KeysTestCase, suffixed_test_name
Expand Down Expand Up @@ -228,6 +229,20 @@ async def test_key_crud_operations(self, **kwargs):
self.assertIsNotNone(deleted_key)
self.assertEqual(rsa_key.id, deleted_key.id)

@PowerShellPreparer("keyvault")
async def test_rsa_public_exponent_mhsm(self, **kwargs):
"""The public exponent of a Managed HSM RSA key can be specified during creation"""
self._skip_if_not_configured(True)
endpoint_url = self.managed_hsm_url

client = self.create_key_client(endpoint_url, is_async=True)
self.assertIsNotNone(client)

key_name = self.get_resource_name("rsa-key")
key = await self._create_rsa_key(client, key_name, hardware_protected=True, public_exponent=17)
public_exponent = byte2int(key.key.e)
assert public_exponent == 17

@parameterized.expand([param(is_hsm=b) for b in [True, False]], name_func=suffixed_test_name)
@PowerShellPreparer("keyvault")
async def test_backup_restore(self, **kwargs):
Expand Down
8 changes: 4 additions & 4 deletions sdk/keyvault/test-resources-post.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ az keyvault security-domain download --hsm-name $hsmName --security-domain-file
Log "Security domain downloaded to '$sdPath'; Managed HSM is now active at '$hsmUrl'"

# Force a sleep to wait for Managed HSM activation to propagate through Cosmos replication. Issue tracked in AzDo.
Log "Sleeping for 30 seconds to allow activation to propagate..."
Start-Sleep -Seconds 30
Log "Sleeping for 120 seconds to allow activation to propagate..."
Start-Sleep -Seconds 120

Log "Creating additional required role assignments for resource access."
New-AzKeyVaultRoleAssignment -HsmName $hsmName -RoleDefinitionName "Managed HSM Crypto Officer" -ObjectID $DeploymentOutputs["CLIENT_OBJECT_ID"]
New-AzKeyVaultRoleAssignment -HsmName $hsmName -RoleDefinitionName "Managed HSM Crypto User" -ObjectID $DeploymentOutputs["CLIENT_OBJECT_ID"]
New-AzKeyVaultRoleAssignment -HsmName $hsmName -RoleDefinitionName "Managed HSM Crypto Officer" -ObjectID $DeploymentOutputs["CLIENT_OBJECTID"]
New-AzKeyVaultRoleAssignment -HsmName $hsmName -RoleDefinitionName "Managed HSM Crypto User" -ObjectID $DeploymentOutputs["CLIENT_OBJECTID"]
Log "Done."