Beispiel #1
0
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
}
Beispiel #3
0
// 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}
}
Beispiel #4
0
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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
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
	})
}
Beispiel #7
0
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))
}
Beispiel #8
0
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[:]))
}
Beispiel #9
0
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
}
Beispiel #10
0
// 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
}
Beispiel #11
0
// 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
}
Beispiel #12
0
// 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)
}
Beispiel #13
0
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
}
Beispiel #14
0
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
}
Beispiel #15
0
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)
	}
}
Beispiel #16
0
// 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
}
Beispiel #18
0
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
}
Beispiel #19
0
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
}
Beispiel #20
0
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)
		}
	}
}
Beispiel #21
0
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
}
Beispiel #22
0
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
}
Beispiel #23
0
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
}
Beispiel #25
0
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)
}
Beispiel #26
0
// 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
}
Beispiel #27
0
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")
}
Beispiel #28
0
// 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
		}
	}
}