Documentation ¶
Index ¶
- Constants
- type Signer
- func FindKey(name string, password string, isUICompatible bool) (Signer, error)
- func GenerateECDSAKey(name string, password string, isUICompatible bool, curve elliptic.Curve, ...) (Signer, error)
- func GenerateRSAKey(name string, password string, isUICompatible bool, bitLength uint32, ...) (Signer, error)
- func GetKeys() ([]Signer, error)
Constants ¶
const ( KeyUsageAllowDecrypt = 0x00000001 // NcryptAllowDecryptFlag KeyUsageAllowSigning = 0x00000002 // NcryptAllowSigningFlag KeyUsageAllowKeyAgreement = 0x00000004 // NcryptAllowKeyAgreementFlag KeyUsageAllowAllUsages = 0x00ffffff // NcryptAllowAllUsages )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Signer ¶
type Signer interface { crypto.Signer // Name returns the PCP key name. Name() string // Size returns the PCP public key size. Size() uint32 // KeyUsage returns the PCP key usage. KeyUsage() uint32 // Delete deletes the PCP key. Delete() error }
Signer implements crypto.Signer and additional functions (i.e. Name()).
This allows a pcpPrivateKey to be usable whenever a crypto.Signer is expected, in addition to allowing the caller to perform additional actions on it that are not typically allowed / implemented by the crypto.Signer interface (i.e Name()).
func FindKey ¶
FindKey tries to open a handle to an existing PCP key by its name and read its public part before creating and returning either a pcpRSAPrivateKey or a pcpECDSAPrivateKey. If the PCP key does not exist, it returns nil.
If password is set, it will be saved in the private key and used before each signature, requiring no interaction from the user. Otherwise, if no password is set, a UI prompt might show up during the signature asking for the password / pin if the key needs one.
We differentiate between :
- PCP keys created with a password set in the Windows UI,
- PCP keys created with a password set programmatically using NCRYPT_PIN_PORPERTY.
A password set via the UI prompt is transformed internally into its SHA-1 digest, while a password set programmatically via NCRYPT_PIN_PROPERTY is transformed internally into its SHA-256 digest. Therefore, if isUICompatible is set to true, we will store the SHA-1 of the password, while we will store its SHA-256 if isUICompatible is set to false.
At the time of writing, and even if we set the NCRYPT_MACHINE_KEY_FLAG flag during creation, the PCP KSP creates a key that applies to the Current User. Therefore, the search will always look for keys that apply for the Current User.
After all operations are done on the resulting key, its handle should be freed by calling the Close() function on the key.
func GenerateECDSAKey ¶
func GenerateECDSAKey(name string, password string, isUICompatible bool, curve elliptic.Curve, keyUsage uint32, overwrite bool) (Signer, error)
GenerateECDSAKey generates a new signing ECDSA PCP Key with the specified name and curve, then returns its corresponding pcpECDSAPrivateKey instance.
If name is empty, it will generate a unique random name beforehand.
If password is empty, it will generate the key with no password / pin, making it usable with no authentication.
If isUICompatible is set to false, and if a password is set, the user will only be able to authenticate to the key programmatically, by setting either of the NCRYPT_PIN_PROPERTY or the NCRYPT_PCP_USAGEAUTH_PROPERTY properties, but never via the Windows UI. If isUICompatible is set to true, and if a password is set, the user will only be able to authenticate to the key via the Windows UI or by setting the NCRYPT_PCP_USAGEAUTH_PROPERTY property, but never by setting the NCRYPT_PIN_PROPERTY property.
If overwrite is set, and if a key with the same name already exists, it will be overwritten.
Supported EC curves are dictated by the (usually at least NIST-P256) and by the PCP KSP. GenerateECDSAKey only supports NIST-P256/P384/P521 which are the only curves supported by the PCP KSP (at the time of writing).
At the time of writing, and even if we set the NCRYPT_MACHINE_KEY_FLAG flag during creation, the PCP KSP creates a key that applies to the Current User. Therefore, GenerateECDSAKey will always generate keys that apply for the Current User.
The key usage can be set by combining the following flags using the OR operation :
- KeyUsageAllowDecrypt
- KeyUsageAllowSigning
- KeyUsageAllowKeyAgreement
- KeyUsageAllowAllUsages
If keyUsage is set to 0 instead, the default key usage will be used, which is SignOnly for ECDSA keys.
TODO: Support UI Policies.
func GenerateRSAKey ¶
func GenerateRSAKey(name string, password string, isUICompatible bool, bitLength uint32, keyUsage uint32, overwrite bool) (Signer, error)
GenerateRSAKey generates a new signing RSA PCP Key with the specified name and bit length, then returns its corresponding pcpRSAPrivateKey instance.
If name is empty, it will generate a unique random name beforehand.
If password is empty, it will generate the key with no password / pin, making it usable with no authentication.
If isUICompatible is set to false, and if a password is set, the user will only be able to authenticate to the key programmatically, by setting either of the NCRYPT_PIN_PROPERTY or the NCRYPT_PCP_USAGEAUTH_PROPERTY properties, but never via the Windows UI. If isUICompatible is set to true, and if a password is set, the user will only be able to authenticate to the key via the Windows UI or by setting the NCRYPT_PCP_USAGEAUTH_PROPERTY property, but never by setting the NCRYPT_PIN_PROPERTY property.
If overwrite is set, and if a key with the same name already exists, it will be overwritten.
Supported RSA bit lengths are dictated by the TPM chip (usually 1024 and 2048) and by the PCP KSP. Therefore, there is no restriction on bitLength by GenerateRSAKey.
At the time of writing, and even if we set the NCRYPT_MACHINE_KEY_FLAG flag during creation, the PCP KSP creates a key that applies to the Current User. Therefore, GenerateRSAKey will always generate keys that apply for the Current User.
The key usage can be set by combining the following flags using the OR operation :
- KeyUsageAllowDecrypt
- KeyUsageAllowSigning
- KeyUsageAllowKeyAgreement
- KeyUsageAllowAllUsages
If keyUsage is set to 0 instead, the default key usage will be used, which is Sign + Decrypt for RSA keys.
TODO: Support UI Policies.