You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
returnnil, nil, fmt.Errorf("could not decode private key: %v", err)
}
This code assumes that all PRIVATE KEY blocks can be parsed by ParsePKCS8PrivateKey and all RSA PRIVATE KEY blocks can be parsed by ParsePKCS1PrivateKey, but Azure Key Vault gives me a PRIVATE KEY block that requires ParsePKCS1PrivateKey.
As far as I know, the block type in PEM files is technically only a hint, not well-specified. I'm not sure whether this bug is really on Azure Key Vault or this library, but it seems reasonable for this library to support Azure Key Vault in practice.
Is this a new or an existing app?
New experiment.
What version of Go are you using (go version)?
go1.22.3
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
set GOARCH=amd64
set GOHOSTARCH=amd64
set GOHOSTOS=windows
...
Repro
Get a JSON blob from Azure Key Vault using az keyvault secret show [...]. Pass the string as bytes into this function to try to decode and set it up as a confidential.Credential that uses its cert:
funcNewCredFromAzureKeyVaultJSON(vaultJSON []byte) (confidential.Credential, error) {
fail:=func(errstring) (confidential.Credential, error) {
return confidential.Credential{}, errors.New(err)
}
vardatastruct {
Valuestring`json:"value"`
}
iferr:=json.Unmarshal(vaultJSON, &data); err!=nil {
returnfail("unable to decode JSON")
}
pfx, err:=base64.StdEncoding.DecodeString(data.Value)
iferr!=nil {
returnfail("unable to decode base64 value")
}
blocks, err:=pkcs12.ToPEM(pfx, "")
iferr!=nil {
returnfail("unable to convert PFX data to PEM blocks")
}
// Multiple blocks are expected. Find the private key and certificates.varpemBuf bytes.Bufferfor_, block:=rangeblocks {
err:=pem.Encode(&pemBuf, block)
iferr!=nil {
returnfail("unable to encode PEM block")
}
}
certs, priv, err:=confidential.CertFromPEM(pemBuf.Bytes(), "")
iferr!=nil {
returnfail("unable to create cert from PEM blocks")
}
returnconfidential.NewCredFromCert(certs, priv)
}
I don't have an example cert or Azure Key Vault response ready at the moment, unfortuantely. I'm not sure how the one I'm using was created. This may only affect a certain kind of certificate.
Expected behavior
Returns a usable confidential.Credential.
Actual behavior
Get an error from confidential.CertFromPEM:
could not decode private key: x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)
This comes from the case "PRIVATE KEY": case, not "RSA PRIVATE KEY".
Possible solution
Replacing confidential.CertFromPEM with a custom copy with this change works, and the resulting confidential.Credential is usable:
case "PRIVATE KEY":
[...]
priv, err = x509.ParsePKCS8PrivateKey(block.Bytes)
+ // Also try ParsePKCS1PrivateKey, because this might not be compatible with ParsePKCS8PrivateKey.+ if err != nil {+ priv, err = x509.ParsePKCS1PrivateKey(block.Bytes)+ }
if err != nil {
return nil, nil, fmt.Errorf("could not decode private key: %v", err)
}
(Keeping track of both errors and returning both might be better, rather than overwriting one with the other.)
The text was updated successfully, but these errors were encountered:
Which version of MSAL Go are you using?
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 (latest)
Where is the issue?
Confidential client - client certificate
microsoft-authentication-library-for-go/apps/confidential/confidential.go
Lines 98 to 116 in 882b562
This code assumes that all
PRIVATE KEY
blocks can be parsed byParsePKCS8PrivateKey
and allRSA PRIVATE KEY
blocks can be parsed byParsePKCS1PrivateKey
, but Azure Key Vault gives me aPRIVATE KEY
block that requiresParsePKCS1PrivateKey
.As far as I know, the block type in PEM files is technically only a hint, not well-specified. I'm not sure whether this bug is really on Azure Key Vault or this library, but it seems reasonable for this library to support Azure Key Vault in practice.
Is this a new or an existing app?
New experiment.
What version of Go are you using (
go version
)?go1.22.3
What operating system and processor architecture are you using (
go env
)?go env
OutputRepro
Get a JSON blob from Azure Key Vault using
az keyvault secret show [...]
. Pass the string as bytes into this function to try to decode and set it up as aconfidential.Credential
that uses its cert:I don't have an example cert or Azure Key Vault response ready at the moment, unfortuantely. I'm not sure how the one I'm using was created. This may only affect a certain kind of certificate.
Expected behavior
Returns a usable
confidential.Credential
.Actual behavior
Get an error from
confidential.CertFromPEM
:could not decode private key: x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)
This comes from the
case "PRIVATE KEY":
case, not"RSA PRIVATE KEY"
.Possible solution
Replacing
confidential.CertFromPEM
with a custom copy with this change works, and the resultingconfidential.Credential
is usable:(Keeping track of both errors and returning both might be better, rather than overwriting one with the other.)
The text was updated successfully, but these errors were encountered: