Example #1
0
func (hq *HashQuery) Parse() error {
	// Require HTTP POST
	if hq.Method != "POST" {
		return ErrorInvalidMethod(hq.Method)
	}
	hq.responseChan = make(ResponseChan)
	var body *bytes.Buffer
	{
		defer hq.Body.Close()
		buf, err := ioutil.ReadAll(hq.Body)
		if err != nil {
			return err
		}
		body = bytes.NewBuffer(buf)
	}
	// Parse hashquery POST data
	n, err := recon.ReadInt(body)
	if err != nil {
		return err
	}
	hq.Digests = make([]string, n)
	for i := 0; i < n; i++ {
		hashlen, err := recon.ReadInt(body)
		if err != nil {
			return err
		}
		hash := make([]byte, hashlen)
		_, err = body.Read(hash)
		if err != nil {
			return err
		}
		hq.Digests[i] = hex.EncodeToString(hash)
	}
	return nil
}
Example #2
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
}