func testReadDigestDups(t *testing.T, testfile string) { f := MustInput(t, "rtt-140.asc") defer f.Close() block, err := armor.Decode(f) if err != nil { t.Fatal(err) } var opkr *OpaqueKeyring for kr := range ReadOpaqueKeyrings(block.Body) { if opkr != nil { t.Fatal("unexpected keyring") } opkr = kr } assert.Equal(t, len(opkr.Packets), 24) pubkey, err := opkr.Parse() assert.Nil(t, err) var buf bytes.Buffer err = WritePackets(&buf, pubkey) assert.Nil(t, err) opkr = nil for kr := range ReadOpaqueKeyrings(bytes.NewBuffer(buf.Bytes())) { if opkr != nil { t.Fatal("unexpected keyring") } opkr = kr } assert.Equal(t, len(opkr.Packets), 24) }
func v3KeyReader(t *testing.T) io.Reader { armorBlock, err := armor.Decode(bytes.NewBufferString(keySigV3Armor)) if err != nil { t.Fatalf("armor Decode failed: %v", err) } return armorBlock.Body }
// Add responds to /pks/add HKP requests. func (w *Worker) Add(a *hkp.Add) { // Parse armored keytext var changes []*KeyChange var readErrors []*ReadKeyResult // Check and decode the armor armorBlock, err := armor.Decode(bytes.NewBufferString(a.Keytext)) if err != nil { a.Response() <- &ErrorResponse{err} return } for readKey := range ReadKeys(armorBlock.Body) { if readKey.Error != nil { readErrors = append(readErrors, readKey) } else { change := w.UpsertKey(readKey.Pubkey) if change.Error != nil { log.Printf("Error updating key [%s]: %v\n", readKey.Pubkey.Fingerprint(), change.Error) } else { go w.notifyChange(change) } changes = append(changes, change) } } a.Response() <- &AddResponse{Changes: changes, Errors: readErrors} }
func (vr *VerifyRequest) VerifySignature() bool { armorData := reArmor(vr.CamliSig) block, _ := armor.Decode(bytes.NewBufferString(armorData)) if block == nil { return vr.fail("can't parse camliSig armor") } var p packet.Packet var err error p, err = packet.Read(block.Body) if err != nil { return vr.fail("error reading PGP packet from camliSig: " + err.Error()) } sig, ok := p.(*packet.Signature) if !ok { return vr.fail("PGP packet isn't a signature packet") } if sig.Hash != crypto.SHA1 && sig.Hash != crypto.SHA256 { return vr.fail("I can only verify SHA1 or SHA256 signatures") } if sig.SigType != packet.SigTypeBinary { return vr.fail("I can only verify binary signatures") } hash := sig.Hash.New() hash.Write(vr.bp) // payload bytes err = vr.PublicKeyPacket.VerifySignature(hash, sig) if err != nil { return vr.fail(fmt.Sprintf("bad signature: %s", err)) } vr.SignerKeyId = vr.PublicKeyPacket.KeyIdString() return true }
// Verify() checks the validity of a signature for some data, // and returns a boolean set to true if valid and an OpenPGP Entity func Verify(data string, signature string, keyring io.Reader) (valid bool, entity *openpgp.Entity, err error) { valid = false // re-armor signature and transform into io.Reader sigReader := strings.NewReader(reArmor(signature)) // decode armor sigBlock, err := armor.Decode(sigReader) if err != nil { panic(err) } if sigBlock.Type != "PGP SIGNATURE" { err = fmt.Errorf("Wrong signature type '%s'", sigBlock.Type) panic(err) } // convert to io.Reader srcReader := strings.NewReader(data) // open the keyring ring, err := openpgp.ReadKeyRing(keyring) if err != nil { panic(err) } entity, err = openpgp.CheckDetachedSignature(ring, srcReader, sigBlock.Body) if err != nil { panic(err) } // we passed, signature is valid valid = true return }
func TestReadKey0ff16c87(t *testing.T) { f := MustInput(t, "0ff16c87.asc") block, err := armor.Decode(f) if err != nil { t.Fatal(err) } var key *Pubkey for keyRead := range ReadKeys(block.Body) { key = keyRead.Pubkey } assert.NotNil(t, key) key.Visit(func(rec PacketRecord) error { _, err = rec.GetOpaquePacket() switch r := rec.(type) { case *Pubkey: assert.NotEmpty(t, r.Packet) case *Subkey: assert.NotEmpty(t, r.Packet) case *Signature: assert.NotEmpty(t, r.Packet) case *UserId: assert.NotEmpty(t, r.Packet) case *UserAttribute: assert.NotEmpty(t, r.Packet) } assert.Nil(t, err) return nil }) }
func ReadEntity(privKeyArmor string) (*openpgp.Entity, error) { block, err := armor.Decode(strings.NewReader(privKeyArmor)) if err != nil { return nil, err } return openpgp.ReadEntity(packet.NewReader(block.Body)) }
func main() { sigReader := strings.NewReader(sig) sigBlock, err := armor.Decode(sigReader) if err != nil { panic(err) } if sigBlock.Type != openpgp.SignatureType { panic("not a signature type") } dataReader := strings.NewReader(data) krfd, err := os.Open("/home/ulfr/.gnupg/pubring.gpg") if err != nil { panic(err) } defer krfd.Close() keyring, err := openpgp.ReadKeyRing(krfd) if err != nil { panic(err) } entity, err := openpgp.CheckDetachedSignature( keyring, dataReader, sigBlock.Body) if err != nil { panic(err) } fmt.Printf("valid signature from key %s\n", hex.EncodeToString(entity.PrimaryKey.Fingerprint[:])) }
func extractEncryptedBodyMime(m *Message) (io.Reader, error) { ps := m.mpContent.parts if len(ps) != 2 { return nil, fmt.Errorf("failed to extract encrypted body, expecting 2 mime parts, got %d", len(ps)) } block, err := armor.Decode(strings.NewReader(ps[1].Body)) if err != nil { return nil, errors.New("armor decode of encrypted body failed: " + err.Error()) } return block.Body, nil }
// readArmored reads an armored block with the given type. func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) { block, err := armor.Decode(r) if err != nil { return } if block.Type != expectedType { return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type) } return block.Body, nil }
// Decrypt tries to decrypt an OpenPGP armored block using the provided decryption keys // and passphrase. If succesfull the plain content of the block is returned as []byte. func Decrypt(d []byte, decryptionKeys *openpgp.EntityList, passphrase string) ([]byte, error) { var armoredBlock *armor.Block var message *openpgp.MessageDetails var plain []byte var err error if d == nil { return nil, nil } // Decode the OpenPGP armored block armoredBlock, err = armor.Decode(bytes.NewReader(d)) if err != nil { return nil, err } // Extract the message from the OpenPGP armored block message, err = openpgp.ReadMessage(armoredBlock.Body, decryptionKeys, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { kp := []byte(passphrase) if symmetric { return kp, nil } for _, k := range keys { err := k.PrivateKey.Decrypt(kp) if err == nil { // If no error were returned, we could succesfully // decrypt the message using the provided private key return nil, nil } } return nil, fmt.Errorf("Unable to decrypt trousseau data store. " + "Invalid passphrase supplied.") }, nil) if err != nil { return nil, fmt.Errorf("unable to decrypt trousseau data store. " + "No private key able to decrypt it found in your keyring.") } // Read the plain message bytes plain, err = ioutil.ReadAll(message.UnverifiedBody) if err != nil { return nil, err } return plain, err }
// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file. func ReadArmoredKeyRing(r io.Reader) (EntityList, error) { block, err := armor.Decode(r) if err == io.EOF { return nil, errors.InvalidArgumentError("no armored data found") } if err != nil { return nil, err } if block.Type != PublicKeyType && block.Type != PrivateKeyType { return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type) } return ReadKeyRing(block.Body) }
func MustInputAscKeys(t *testing.T, name string) (result []*Pubkey) { f := MustInput(t, name) defer f.Close() block, err := armor.Decode(f) if err != nil { t.Fatal(err) } for keyRead := range ReadKeys(block.Body) { if keyRead.Error != nil { t.Fatal(keyRead.Error) } result = append(result, keyRead.Pubkey) } return }
func extractInlineBody(body string) (io.Reader, error) { start := strings.Index(body, beginPgpMessage) if start == -1 { return nil, nil } end := strings.Index(body, endPgpMessage) if end == -1 { return nil, errors.New("End of inline PGP message not found") } armored := body[start:(end + len(endPgpMessage))] block, err := armor.Decode(bytes.NewReader([]byte(armored))) if err != nil { return nil, errors.New("armor decode of encrypted body failed: " + err.Error()) } return block.Body, nil }
func TestValidateKey(t *testing.T) { f := MustInput(t, "tails.asc") defer f.Close() block, err := armor.Decode(f) if err != nil { t.Fatal(err) } var keys []*Pubkey for keyRead := range ReadKeys(block.Body) { keys = append(keys, keyRead.Pubkey) } assert.Equal(t, 1, len(keys)) assert.Equal(t, 2, len(keys[0].userIds)) for i := 0; i < 2; i++ { assert.NotEmpty(t, keys[0].userIds[i].ScopedDigest) } }
// Test packet.Read error handling in OpaquePacket.Parse, // which attempts to re-read an OpaquePacket as a supported // Packet type. func TestOpaqueParseReason(t *testing.T) { armorBlock, err := armor.Decode(bytes.NewBufferString(UnsupportedKeyArmor)) if err != nil { t.Fatalf("armor Decode failed: %v", err) } or := NewOpaqueReader(armorBlock.Body) count := 0 badPackets := 0 var uid *UserId for { op, err := or.Next() if err == io.EOF { break } else if err != nil { t.Errorf("#%d: opaque read error: %v", count, err) break } // try to parse opaque packet p, err := op.Parse() switch pkt := p.(type) { case *UserId: uid = pkt case *OpaquePacket: // If an OpaquePacket can't re-parse, packet.Read // certainly had its reasons. if pkt.Reason == nil { t.Errorf("#%d: opaque packet, no reason", count) } else { badPackets++ } } count++ } const expectedBad = 2 // Test post-conditions, make sure we actually parsed packets as expected. if badPackets != expectedBad { t.Errorf("unexpected # unparseable packets: %d (want %d)", badPackets, expectedBad) } if uid == nil { t.Errorf("failed to find expected UID in unsupported keyring") } else if uid.Id != "Armin M. Warda <*****@*****.**>" { t.Errorf("unexpected UID: %v", uid.Id) } }
func DelegateToSKS(searchquery string, toServer string) (keys []*Pubkey, err error) { resp, errG := http.Get(fmt.Sprintf("http://" + toServer + "/pks/lookup?op=get&search=" + searchquery)) if errG != nil { err = errG return } if resp.StatusCode == http.StatusNotFound { return } // Store response in memory. Connection may timeout if we // read directly from it while loading. var body *bytes.Buffer { defer resp.Body.Close() bodyBuf, errR := ioutil.ReadAll(resp.Body) if errR != nil { log.Println("Delegate: Reading http response body:", errR) err = errR return } body = bytes.NewBuffer(bodyBuf) } // Check and decode the armor armorBlock, errD := armor.Decode(body) if errD != nil { log.Println("armor.decode", err) return } for readKey := range ReadKeys(armorBlock.Body) { if readKey.Error != nil { fmt.Println("ReadKeys", readKey.Error) } else { log.Println("delegate.go: Found a key from request!! = ", readKey.Pubkey.KeyId()) //fmt.Println("delegate.go: Found a key from request!! = ", readKey.Pubkey.KeyId()) keys = append(keys, readKey.Pubkey) } } return }
func verifyMimeSignature(m *Message, keysrc KeySource) *VerifyStatus { if !m.IsMultipart() || m.ctSecondary != "signed" { return createVerifyFailure("Not a multipart/signed message") } ps := m.mpContent.parts if len(ps) != 2 { return createVerifyFailure(fmt.Sprintf("cannot extract signature, expecting 2 mime parts, got %d", len(ps))) } sig := bytes.NewReader([]byte(ps[1].Body)) sigBlock, err := armor.Decode(sig) if err != nil { return createVerifyFailure("error decoding armored signature: " + err.Error()) } status := checkSignature(keysrc, ps[0].rawContent, sigBlock) if isVerifiedSignature(status) { processMimePlaintext(m, ps[0].rawContent) status.Message = m } return status }
func loadPGPKey(path string, defaultPath string) (*openpgp.Entity, error) { if path == "" { path = getHomePath(defaultPath) } f, err := os.Open(path) if err != nil { return nil, err } defer f.Close() block, err := armor.Decode(f) if err != nil { return nil, err } el, err := openpgp.ReadKeyRing(block.Body) if err != nil { return nil, err } if len(el) != 1 { return nil, fmt.Errorf("Key file %s contained %d keys, expecting 1", path, len(el)) } return el[0], nil }
func TestUatRtt(t *testing.T) { f := MustInput(t, "uat.asc") defer f.Close() block, err := armor.Decode(f) if err != nil { t.Fatal(err) } var p packet.Packet for { p, err = packet.Read(block.Body) if err != nil { break } if uat, is := p.(*packet.UserAttribute); is { var buf bytes.Buffer uat.Serialize(&buf) or := packet.NewOpaqueReader(bytes.NewBuffer(buf.Bytes())) op, _ := or.Next() assert.Equal(t, buf.Bytes()[3:], op.Contents) } } }
func openArmoredPublicKeyFile(reader io.ReadCloser) (*packet.PublicKey, error) { defer reader.Close() var lr = io.LimitReader(reader, publicKeyMaxSize) block, _ := armor.Decode(lr) if block == nil { return nil, errors.New("Couldn't find PGP block in public key file") } if block.Type != "PGP PUBLIC KEY BLOCK" { return nil, errors.New("Invalid public key blob.") } p, err := packet.Read(block.Body) if err != nil { return nil, fmt.Errorf("Invalid public key blob: %v", err) } pk, ok := p.(*packet.PublicKey) if !ok { return nil, fmt.Errorf("Invalid public key blob; not a public key packet") } return pk, nil }
func decryptMimeMessage(m *Message, keysrc KeySource, passphrase []byte) *DecryptionStatus { parts := m.mpContent.parts if len(parts) != 2 { return createFailureStatus(fmt.Sprintf("failed to extract encrypted body, expecting 2 mime parts, got %d", len(parts))) } block, err := armor.Decode(strings.NewReader(parts[1].Body)) if err != nil { return createFailureStatus("armor decode of encrypted body failed: " + err.Error()) } bs, status := decryptCiphertext(keysrc, block.Body, passphrase) if bs == nil { return status } err = processMimePlaintext(m, bs) if err != nil { status.Code = DecryptFailed status.FailureMessage = "error building plaintext message: " + err.Error() return status } status.Message = m return status }
func decrypt(s string) (string, error) { if s == "" { return "", nil } raw, err := armor.Decode(strings.NewReader(s)) if err != nil { return "", err } d, err := openpgp.ReadMessage(raw.Body, keys, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { kp := []byte(password) if symmetric { return kp, nil } for _, k := range keys { err := k.PrivateKey.Decrypt(kp) if err == nil { return nil, nil } } return nil, fmt.Errorf("Whether no valid private key for" + "store decryption was available or " + "supplied password was invalid") }, nil) if err != nil { return "", err } bytes, err := ioutil.ReadAll(d.UnverifiedBody) return string(bytes), err }
func Decrypt(decryptionKeys *openpgp.EntityList, s, passphrase string) ([]byte, error) { if s == "" { return nil, nil } armorBlock, err := armor.Decode(strings.NewReader(s)) if err != nil { return nil, err } d, err := openpgp.ReadMessage(armorBlock.Body, decryptionKeys, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { kp := []byte(passphrase) if symmetric { return kp, nil } for _, k := range keys { err := k.PrivateKey.Decrypt(kp) if err == nil { return nil, nil } } return nil, fmt.Errorf("Unable to decrypt trousseau data store. " + "Invalid passphrase supplied.") }, nil) if err != nil { return nil, err } bytes, err := ioutil.ReadAll(d.UnverifiedBody) return bytes, err }
func TestV3NoUidSig(t *testing.T) { key := MustInputAscKey(t, "0xd46b7c827be290fe4d1f9291b1ebc61a.asc") assert.Equal(t, "0005127a8b7da8c32998d7e81dc92540", key.Md5) assert.Equal(t, "0760df64b3d82239", key.KeyId()) f := MustInput(t, "0xd46b7c827be290fe4d1f9291b1ebc61a.asc") defer f.Close() block, err := armor.Decode(f) if err != nil { t.Fatal(err) } var kr *OpaqueKeyring for opkr := range ReadOpaqueKeyrings(block.Body) { kr = opkr } sort.Sort(sksPacketSorter{kr.Packets}) h := md5.New() for _, opkt := range kr.Packets { binary.Write(h, binary.BigEndian, int32(opkt.Tag)) binary.Write(h, binary.BigEndian, int32(len(opkt.Contents))) h.Write(opkt.Contents) } md5 := hex.EncodeToString(h.Sum(nil)) assert.Equal(t, "0005127a8b7da8c32998d7e81dc92540", md5) }
// Decode finds the first clearsigned message in data and returns it, as well // as the suffix of data which remains after the message. func Decode(data []byte) (b *Block, rest []byte) { // start begins with a newline. However, at the very beginning of // the byte array, we'll accept the start string without it. rest = data if bytes.HasPrefix(data, start[1:]) { rest = rest[len(start)-1:] } else if i := bytes.Index(data, start); i >= 0 { rest = rest[i+len(start):] } else { return nil, data } // Consume the start line. _, rest = getLine(rest) var line []byte b = &Block{ Headers: make(textproto.MIMEHeader), } // Next come a series of header lines. for { // This loop terminates because getLine's second result is // always smaller than its argument. if len(rest) == 0 { return nil, data } // An empty line marks the end of the headers. if line, rest = getLine(rest); len(line) == 0 { break } i := bytes.Index(line, []byte{':'}) if i == -1 { return nil, data } key, val := line[0:i], line[i+1:] key = bytes.TrimSpace(key) val = bytes.TrimSpace(val) b.Headers.Add(string(key), string(val)) } firstLine := true for { start := rest line, rest = getLine(rest) if bytes.Equal(line, endText) { // Back up to the start of the line because armor expects to see the // header line. rest = start break } // The final CRLF isn't included in the hash so we don't write it until // we've seen the next line. if firstLine { firstLine = false } else { b.Bytes = append(b.Bytes, crlf...) } if bytes.HasPrefix(line, dashEscape) { line = line[2:] } line = bytes.TrimRight(line, " \t") b.Bytes = append(b.Bytes, line...) b.Plaintext = append(b.Plaintext, line...) b.Plaintext = append(b.Plaintext, lf) } // We want to find the extent of the armored data (including any newlines at // the end). i := bytes.Index(rest, end) if i == -1 { return nil, data } i += len(end) for i < len(rest) && (rest[i] == '\r' || rest[i] == '\n') { i++ } armored := rest[:i] rest = rest[i:] var err error b.ArmoredSignature, err = armor.Decode(bytes.NewBuffer(armored)) if err != nil { return nil, data } return b, rest }
func TestDupSig(t *testing.T) { { f := MustInput(t, "252B8B37.dupsig.asc") defer f.Close() block, err := armor.Decode(f) if err != nil { t.Fatal(err) } r := packet.NewOpaqueReader(block.Body) var packets []*packet.OpaquePacket for { if op, err := r.Next(); err != nil { break } else { packets = append(packets, op) t.Log("raw:", op) } } sksDigest := sksDigestOpaque(packets, md5.New()) assert.Equal(t, sksDigest, "6d57b48c83d6322076d634059bb3b94b") } // Read a key { f := MustInput(t, "252B8B37.dupsig.asc") defer f.Close() block, err := armor.Decode(f) if err != nil { t.Fatal(err) } var key *Pubkey for keyRead := range readKeys(block.Body) { assert.Nil(t, keyRead.Error) key = keyRead.Pubkey } var packets []*packet.OpaquePacket key.Visit(func(rec PacketRecord) error { op, err := rec.GetOpaquePacket() assert.Nil(t, err) packets = append(packets, op) return err }) r := packet.NewOpaqueReader(bytes.NewBuffer(key.Unsupported)) for op, err := r.Next(); err == nil; op, err = r.Next() { packets = append(packets, op) } sksDigest := sksDigestOpaque(packets, md5.New()) assert.Equal(t, sksDigest, "6d57b48c83d6322076d634059bb3b94b") } // Now read & resolve key := MustInputAscKey(t, "252B8B37.dupsig.asc") key.Visit(func(rec PacketRecord) error { op, err := rec.GetOpaquePacket() assert.Nil(t, err) t.Log("parsed:", op) return nil }) r := packet.NewOpaqueReader(bytes.NewBuffer(key.Unsupported)) for op, err := r.Next(); err == nil; op, err = r.Next() { t.Log("parsed:", op) } assert.Equal(t, key.Md5, "6d57b48c83d6322076d634059bb3b94b") }
// Add responds to /pks/add HKP requests. func (w *Worker) Add(a *hkp.Add) { // Parse armored keytext var changes []*KeyChange var readErrors []*ReadKeyResult // Check and decode the armor armorBlock, err := armor.Decode(bytes.NewBufferString(a.Keytext)) if err != nil { a.Response() <- &ErrorResponse{err} return } for readKey := range ReadKeys(armorBlock.Body) { if readKey.Error != nil { readErrors = append(readErrors, readKey) } else { log.Println("add.go: Found a key from request!! = ", readKey.Pubkey.KeyId()) //SignPubKeyPKS(*readKey.Pubkey) //First Check weather we are the authority for it underAuth := IsUnderAuth(*readKey.Pubkey) if underAuth != nil { change1 := &KeyChange{} change1.Type = NotInOurAuthority change1.ChangeMessage = underAuth.Error() changes = append(changes, change1) log.Println(underAuth.Error()) } else { //Checked weather its under our own authority if readKey.Pubkey.Sha256 == a.ShaOfTarget || len(a.ShaOfTarget) != 64 { //Extract Email usrID := readKey.Pubkey.primaryUid userEmail := usrID.UserId.Email //Email extracted req_PubKey := readKey.Pubkey reqChanges := w.FindChanges(readKey.Pubkey) isVerified := false var otlState int if reqChanges.Type == KeyAdded { //Key not found hence new key added log.Println("add.go:Request has New Key (ID): ", req_PubKey.Fingerprint()) isVerified, otlState = w.Verify(userEmail, a.Keytext, *req_PubKey, int16(1)) log.Println("add.go:Is Requested Key Verified??: ", isVerified) } else if reqChanges.Type == KeyModified { //key will be changed/updated with new contents log.Println("add.go:Request Modifies key (ID): ", req_PubKey.Fingerprint()) isVerified, otlState = w.Verify(userEmail, a.Keytext, *req_PubKey, int16(1)) log.Println("add.go:Is Requested Key Verified??: ", isVerified) } else if reqChanges.Type == KeyNotChanged { log.Println("add.go:request doesnt make change to key(id) : ", req_PubKey.Fingerprint()) w.notifyChange(reqChanges) changes = append(changes, reqChanges) a.Response() <- &AddResponse{Changes: changes, Errors: readErrors} return } if isVerified { if reqChanges.Type != KeyNotChanged { //If key is verified then call upsert as //it will eventually insert data in to db log.Println("add.go:Key Verified...") //Key verified hence add signature of PKS //Check weather a key with same email exists or not. repKeys, err := w.LookupKeys(userEmail, 2) replacesKey := false if err == ErrKeyNotFound || len(repKeys) <= 0 { //No key found by Email replacesKey = false } else { replacesKey = true } //Replace End //Signing Start signed_Key, err := SignKeyAfterVerification(a.Keytext) if err != nil { log.Println("Error signing key ", err) a.Response() <- &ErrorResponse{err} return } armorBlock, err := armor.Decode(bytes.NewBufferString(signed_Key)) if err != nil { log.Println("decoding signed key ", err) a.Response() <- &ErrorResponse{err} return } for readKey := range ReadKeys(armorBlock.Body) { if readKey.Error != nil { readErrors = append(readErrors, readKey) } else { if _, err = w.Begin(); err != nil { a.Response() <- &ErrorResponse{err} return } change := w.UpsertKey(readKey.Pubkey) if err = w.Commit(); err != nil { a.Response() <- &ErrorResponse{err} return } //Signing END if change.Error != nil { log.Printf("Error updating key [%s]: %v\n", readKey.Pubkey.Fingerprint(), change.Error) } else { if replacesKey { //Delete Old key if _, err = w.Begin(); err != nil { log.Println("replaceDelete", err) a.Response() <- &ErrorResponse{err} return } change, err1 := w.deleteKey(repKeys[0]) if err = w.Commit(); err != nil { log.Println("replaceDelete", err) a.Response() <- &ErrorResponse{err} return } if err1 != nil { log.Println("replaceDelete", err1) a.Response() <- &ErrorResponse{err1} return } w.notifyChange(&change) changes = append(changes, &change) } } //Notify using changes w.notifyChange(change) changes = append(changes, change) } } } else { w.notifyChange(reqChanges) changes = append(changes, reqChanges) } } else { reqChanges.Type = EmailNotVerified reqChanges.Fingerprint = "" if otlState == OTLNewOtlMade { resKeys, err := w.LookupKeys(userEmail, 2) replacesKey := false if err == ErrKeyNotFound || len(resKeys) <= 0 { //No key found by Email replacesKey = false } else { replacesKey = true } message := fmt.Sprintf("A verification link has been sent to %s.The link will expire in %d day/s.\n Please check your email.", userEmail, ExpInDays) if replacesKey { message += " * A key with same email already exists on the server.If you verify above request it will replace the key with id " + strings.ToUpper(resKeys[0].KeyId()) } reqChanges.ChangeMessage = message log.Println("OTL NOT FOUND!!") } else if otlState == OTLExpired { reqChanges.ChangeMessage = fmt.Sprintf("The link you have clicked has expired. Please submit your key again.") log.Println("OTL Expired!!") } else if otlState == OTLNotVerified { reqChanges.ChangeMessage = fmt.Sprintf("A request for same key has already been made.Please Check your email %s", userEmail) log.Println("OTL Not Verified!!") } else if otlState == ErrorSendingMail { reqChanges.ChangeMessage = fmt.Sprintf("Unfortunately we were unable to send an e-mail to %s Please Add key after sometime with new request", userEmail) } changes = append(changes, reqChanges) } //EDIT END } a.Response() <- &AddResponse{Changes: changes, Errors: readErrors} return } a.Response() <- &AddResponse{Changes: changes, Errors: readErrors} return } } }