peridot/vendor/github.com/ProtonMail/gopenpgp/v2/crypto/key_clear.go
2022-07-07 22:13:21 +02:00

129 lines
2.5 KiB
Go

package crypto
import (
"crypto/dsa" //nolint:staticcheck
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"errors"
"math/big"
"github.com/ProtonMail/go-crypto/openpgp/ecdh"
"github.com/ProtonMail/go-crypto/openpgp/elgamal"
)
func (sk *SessionKey) Clear() (ok bool) {
clearMem(sk.Key)
return true
}
func (key *Key) ClearPrivateParams() (ok bool) {
num := key.clearPrivateWithSubkeys()
key.entity.PrivateKey = nil
for k := range key.entity.Subkeys {
key.entity.Subkeys[k].PrivateKey = nil
}
return num > 0
}
func (key *Key) clearPrivateWithSubkeys() (num int) {
num = 0
if key.entity.PrivateKey != nil {
err := clearPrivateKey(key.entity.PrivateKey.PrivateKey)
if err == nil {
num++
}
}
for k := range key.entity.Subkeys {
if key.entity.Subkeys[k].PrivateKey != nil {
err := clearPrivateKey(key.entity.Subkeys[k].PrivateKey.PrivateKey)
if err == nil {
num++
}
}
}
return num
}
func clearPrivateKey(privateKey interface{}) error {
switch priv := privateKey.(type) {
case *rsa.PrivateKey:
return clearRSAPrivateKey(priv)
case *dsa.PrivateKey:
return clearDSAPrivateKey(priv)
case *elgamal.PrivateKey:
return clearElGamalPrivateKey(priv)
case *ecdsa.PrivateKey:
return clearECDSAPrivateKey(priv)
case *ed25519.PrivateKey:
return clearEdDSAPrivateKey(priv)
case *ecdh.PrivateKey:
return clearECDHPrivateKey(priv)
default:
return errors.New("gopenpgp: unknown private key")
}
}
func clearBigInt(n *big.Int) {
w := n.Bits()
for k := range w {
w[k] = 0x00
}
}
func clearMem(w []byte) {
for k := range w {
w[k] = 0x00
}
}
func clearRSAPrivateKey(rsaPriv *rsa.PrivateKey) error {
clearBigInt(rsaPriv.D)
for idx := range rsaPriv.Primes {
clearBigInt(rsaPriv.Primes[idx])
}
clearBigInt(rsaPriv.Precomputed.Qinv)
clearBigInt(rsaPriv.Precomputed.Dp)
clearBigInt(rsaPriv.Precomputed.Dq)
for idx := range rsaPriv.Precomputed.CRTValues {
clearBigInt(rsaPriv.Precomputed.CRTValues[idx].Exp)
clearBigInt(rsaPriv.Precomputed.CRTValues[idx].Coeff)
clearBigInt(rsaPriv.Precomputed.CRTValues[idx].R)
}
return nil
}
func clearDSAPrivateKey(priv *dsa.PrivateKey) error {
clearBigInt(priv.X)
return nil
}
func clearElGamalPrivateKey(priv *elgamal.PrivateKey) error {
clearBigInt(priv.X)
return nil
}
func clearECDSAPrivateKey(priv *ecdsa.PrivateKey) error {
clearBigInt(priv.D)
return nil
}
func clearEdDSAPrivateKey(priv *ed25519.PrivateKey) error {
clearMem(*priv)
return nil
}
func clearECDHPrivateKey(priv *ecdh.PrivateKey) error {
clearMem(priv.D)
return nil
}