Skip to content

Commit

Permalink
Support looking up private keys in the current user cert store.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 563330939
  • Loading branch information
CertoToStore Team authored and copybara-github committed Sep 7, 2023
1 parent c4d4bf9 commit c12d26c
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions certtostore_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ import (
"unsafe"

"github.com/google/deck"
"github.com/hashicorp/go-multierror"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/sys/windows"
"github.com/hashicorp/go-multierror"
)

// WinCertStorage provides windows-specific additions to the CertStorage interface.
Expand Down Expand Up @@ -1197,7 +1197,7 @@ func keyMetadata(kh uintptr, store *WinCertStore) (*Key, error) {
// store.Prov to tell us which provider a given key resides in. Instead, we
// lookup the provider directly from the key properties.
if impl == nCryptImplSoftwareFlag {
uc, lc, err = softwareKeyContainers(uc)
uc, lc, err = softwareKeyContainers(uc, store.storeDomain())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1525,11 +1525,24 @@ func copyFile(from, to string) error {

// softwareKeyContainers returns the file path for a software backed key. If the key
// was finalized with with NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG, it also returns its
// equivalent CryptoAPI key file path. It assumes the key is persisted in the system keystore.
// equivalent CryptoAPI key file path.
// https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptfinalizekey.
func softwareKeyContainers(uniqueID string) (string, string, error) {
var cngRoot = os.Getenv("ProgramData") + `\Microsoft\Crypto\Keys\`
var capiRoot = os.Getenv("ProgramData") + `\Microsoft\Crypto\RSA\MachineKeys\`
func softwareKeyContainers(uniqueID string, storeDomain uint32) (string, string, error) {
var cngRoot, capiRoot string
switch storeDomain {
case certStoreLocalMachine:
cngRoot = os.Getenv("ProgramData") + `\Microsoft\Crypto\Keys\`
capiRoot = os.Getenv("ProgramData") + `\Microsoft\Crypto\RSA\MachineKeys\`
case certStoreCurrentUser:
cngRoot = os.Getenv("AppData") + `\Microsoft\Crypto\Keys\`
sid, err := UserSID()
if err != nil {
return "", "", fmt.Errorf("unable to determine user SID: %v", err)
}
capiRoot = fmt.Sprintf(`%s\Microsoft\Crypto\RSA\%s\`, os.Getenv("AppData"), sid)
default:
return "", "", fmt.Errorf("unexpected store domain %d", storeDomain)
}

// Determine the key type, so that we know which container we are
// working with.
Expand Down

0 comments on commit c12d26c

Please sign in to comment.