Created
January 17, 2018 06:29
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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