Beispiel #1
0
func readHashes(db *openpgp.DB) chan *conflux.Zp {
	hashes := make(chan *conflux.Zp)
	go func() {
		defer close(hashes)
		rows, err := db.DB.Query("SELECT md5 FROM openpgp_pubkey")
		if err != nil {
			die(err)
		}
		for rows.Next() {
			var md5str string
			if err = rows.Scan(&md5str); err != nil {
				die(err)
			}
			digest, err := hex.DecodeString(md5str)
			if err != nil {
				log.Println("Bad md5:", md5str)
				continue
			}
			digest = recon.PadSksElement(digest)
			digestZp := conflux.Zb(conflux.P_SKS, digest)
			hashes <- digestZp
		}
		if err = rows.Err(); err != nil {
			log.Println("Error during hash query:", err)
		}
	}()
	return hashes
}
Beispiel #2
0
func DigestZp(digest string) (*Zp, error) {
	buf, err := hex.DecodeString(digest)
	if err != nil {
		return nil, err
	}
	buf = recon.PadSksElement(buf)
	return Zb(P_SKS, buf), nil
}
Beispiel #3
0
func (ec *loadCmd) loadAllKeys(path string) {
	keyfiles, err := filepath.Glob(path)
	if err != nil {
		die(err)
	}
	for _, keyfile := range keyfiles {
		var f *os.File
		if f, err = os.Open(keyfile); err != nil {
			log.Println("Failed to open", keyfile, ":", err)
			continue
		}
		defer f.Close()
		log.Println("Loading keys from", keyfile)
		defer ec.flushDb()
		for keyRead := range openpgp.ReadKeys(f) {
			if keyRead.Error != nil {
				log.Println("Error reading key:", keyRead.Error)
				continue
			}
			digest, err := hex.DecodeString(keyRead.Pubkey.Md5)
			if err != nil {
				log.Println("bad digest:", keyRead.Pubkey.Md5)
				continue
			}
			digest = recon.PadSksElement(digest)
			digestZp := conflux.Zb(conflux.P_SKS, digest)
			err = ec.ptree.Insert(digestZp)
			if err != nil {
				log.Println("Error inserting digest ", keyRead.Pubkey.Md5, ":", err)
				continue
			}
			err = ec.insertKey(keyRead)
			if err != nil {
				log.Println("Error inserting key", keyRead.Pubkey.Md5, "into database:", err)
				// Attempt to remove digest from ptree, since it was not successfully loaded
				ec.ptree.Remove(digestZp)
				continue
			}
		}
	}
}
Beispiel #4
0
func (r *SksPeer) requestChunk(rcvr *recon.Recover, chunk []*Zp) (err error) {
	var remoteAddr string
	remoteAddr, err = rcvr.HkpAddr()
	if err != nil {
		return err
	}
	// Make an sks hashquery request
	hqBuf := bytes.NewBuffer(nil)
	err = recon.WriteInt(hqBuf, len(chunk))
	if err != nil {
		return err
	}
	for _, z := range chunk {
		zb := z.Bytes()
		zb = recon.PadSksElement(zb)
		// Hashquery elements are 16 bytes (length_of(P_SKS)-1)
		zb = zb[:len(zb)-1]
		err = recon.WriteInt(hqBuf, len(zb))
		if err != nil {
			return err
		}
		_, err = hqBuf.Write(zb)
		if err != nil {
			return err
		}
	}
	resp, err := http.Post(fmt.Sprintf("http://%s/pks/hashquery", remoteAddr),
		"sks/hashquery", bytes.NewReader(hqBuf.Bytes()))
	if err != nil {
		return err
	}
	// Store response in memory. Connection may timeout if we
	// read directly from it while loading.
	var body *bytes.Buffer
	{
		defer resp.Body.Close()
		bodyBuf, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		body = bytes.NewBuffer(bodyBuf)
	}
	var nkeys, keyLen int
	nkeys, err = recon.ReadInt(body)
	if err != nil {
		return err
	}
	log.Println("Response from server:", nkeys, " keys found")
	for i := 0; i < nkeys; i++ {
		keyLen, err = recon.ReadInt(body)
		if err != nil {
			return err
		}
		keyBuf := bytes.NewBuffer(nil)
		_, err = io.CopyN(keyBuf, body, int64(keyLen))
		if err != nil {
			return err
		}
		log.Println("Key#", i+1, ":", keyLen, "bytes")
		// Merge locally
		recoverKey := RecoverKey{
			Keytext:  keyBuf.Bytes(),
			Source:   rcvr.RemoteAddr.String(),
			response: make(chan hkp.Response)}
		go func() {
			r.RecoverKey <- recoverKey
		}()
		resp := <-recoverKey.response
		if resp, ok := resp.(*RecoverKeyResponse); ok {
			if resp.Error() != nil {
				log.Println("Error adding key:", resp.Error())
			}
		} else if resp != nil {
			log.Println("Error adding key:", resp.Error())
		} else {
			log.Println("Empty response from recovering key!")
		}
	}
	// Read last two bytes (CRLF, why?), or SKS will complain.
	body.Read(make([]byte, 2))
	return
}