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 }
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 }