Skip to content

Instantly share code, notes, and snippets.

@sowbug
Created January 17, 2018 06:29
Show Gist options
  • Save sowbug/5c1a950ea21b169975375d470b52fbfb to your computer and use it in GitHub Desktop.
Save sowbug/5c1a950ea21b169975375d470b52fbfb to your computer and use it in GitHub Desktop.
Demo code showing problem with GnuPG keys generated in golang.org/x/crypto/openpgp
// some of this was adapted from https://gist.github.com/eliquious/9e96017f47d9bd43cdf9
func (sg SecretGenerator) GetPGPKey(passphrase string) string {
var config packet.Config
config.Time = func() time.Time {
return time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC)
}
uid := packet.NewUserId(sg.GetFriendlyName("main"), "", "")
if uid == nil {
log.Println("NewUserId failed")
return "ERROR"
}
curve := elliptic.P256()
rand := bytes.NewReader(sg.Entropy("keys/primary",
curve.Params().BitSize / 8 + 8))
sign_priv, err := ecdsa.GenerateKey(curve, rand)
if err != nil {
log.Printf("s generate key error: %s\n", err)
return "ERROR"
}
rand = bytes.NewReader(sg.Entropy("keys/subkey",
curve.Params().BitSize / 8 + 8))
enc_priv, err := ecdsa.GenerateKey(curve, rand)
if err != nil {
log.Printf("e generate key error: %s\n", err)
return "ERROR"
}
e := &openpgp.Entity{
PrimaryKey: packet.NewECDSAPublicKey(config.Time(), &sign_priv.PublicKey),
PrivateKey: packet.NewECDSAPrivateKey(config.Time(), sign_priv),
Identities: make(map[string]*openpgp.Identity),
}
isPrimaryId := true
e.Identities[uid.Id] = &openpgp.Identity{
Name: uid.Name,
UserId: uid,
SelfSignature: &packet.Signature{
CreationTime: config.Time(),
SigType: packet.SigTypePositiveCert,
PubKeyAlgo: packet.PubKeyAlgoECDSA,
Hash: config.Hash(),
IsPrimaryId: &isPrimaryId,
FlagsValid: true,
FlagSign: true,
FlagCertify: true,
IssuerKeyId: &e.PrimaryKey.KeyId,
},
}
e.Subkeys = make([]openpgp.Subkey, 1)
e.Subkeys[0] = openpgp.Subkey{
PublicKey: packet.NewECDSAPublicKey(config.Time(), &enc_priv.PublicKey),
PrivateKey: packet.NewECDSAPrivateKey(config.Time(), enc_priv),
Sig: &packet.Signature{
CreationTime: config.Time(),
SigType: packet.SigTypeSubkeyBinding,
PubKeyAlgo: packet.PubKeyAlgoECDH,
Hash: config.Hash(),
FlagsValid: true,
FlagEncryptStorage: true,
FlagEncryptCommunications: true,
IssuerKeyId: &e.PrimaryKey.KeyId,
},
}
e.Subkeys[0].PublicKey.IsSubkey = true
e.Subkeys[0].PrivateKey.IsSubkey = true
// Sign identities
for _, id := range e.Identities {
err := id.SelfSignature.SignUserId(uid.Id, e.PrimaryKey, e.PrivateKey, nil)
if err != nil {
log.Printf("signing failed %s\n", err)
return "ERROR"
}
}
// Sign subkeys
for _, subkey := range e.Subkeys {
err := subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, nil)
if err != nil {
log.Printf("signing failed %s\n", err)
return "ERROR"
}
}
buffer := &bytes.Buffer{}
w, err := armor.Encode(buffer, openpgp.PublicKeyType, map[string]string{})
e.Serialize(w)
w.Close()
return buffer.String()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment