package azurekeyvault import ( "context" "crypto/ecdsa" "crypto/elliptic" "crypto/sha512" "fmt" "math/big" "os" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys" "github.com/modelcontextprotocol/registry/cmd/publisher/auth" ) func GetSignatureProvider(vaultName, keyName string) (auth.Signer, error) { if vaultName == "" { return nil, fmt.Errorf("--vault option (vault name) is required") } if keyName == "" { return nil, fmt.Errorf("--key option (key name) is required") } return Signer{ vaultName: vaultName, keyName: keyName, }, nil } type Signer struct { vaultName string keyName string } func (d Signer) GetSignedTimestamp(ctx context.Context) (*string, []byte, error) { fmt.Fprintf(os.Stdout, "Signing using Azure Key Vault %s and key %s\n", d.vaultName, d.keyName) cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { return nil, nil, fmt.Errorf("authentication to Azure failed: %w", err) } vaultURL := fmt.Sprintf("https://%s.vault.azure.net/", d.vaultName) client, err := azkeys.NewClient(vaultURL, cred, nil) if err != nil { return nil, nil, fmt.Errorf("failed to create Key Vault client: %w", err) } keyResp, err := client.GetKey(ctx, d.keyName, "", nil) if err != nil { return nil, nil, fmt.Errorf("failed to retrieve key for public parameters: %w", err) } if *keyResp.Key.Kty != azkeys.KeyTypeEC && *keyResp.Key.Kty != azkeys.KeyTypeECHSM { return nil, nil, fmt.Errorf("unsupported key type: kty: %s (only EC or EC-HSM keys are supported)", *keyResp.Key.Kty) } if *keyResp.Key.Crv != azkeys.CurveNameP384 { return nil, nil, fmt.Errorf("unsupported curve: %s (only P-384 is supported)", *keyResp.Key.Crv) } fmt.Fprintln(os.Stdout, "Successfully read the public key from Key Vault.") auth.PrintEcdsaP384KeyInfo(ecdsa.PublicKey{ Curve: elliptic.P384(), X: new(big.Int).SetBytes(keyResp.Key.X), Y: new(big.Int).SetBytes(keyResp.Key.Y), }) timestamp := auth.GetTimestamp() digest := sha512.Sum384([]byte(timestamp)) alg := azkeys.SignatureAlgorithmES384 fmt.Fprintln(os.Stdout, "Executing the sign request...") signResp, err := client.Sign(ctx, d.keyName, "", azkeys.SignParameters{ Algorithm: &alg, Value: digest[:], }, nil) if err != nil { return nil, nil, fmt.Errorf("failed to sign message: %w", err) } return ×tamp, signResp.Result, nil }