package main import ( "bytes" "crypto/tls" "crypto/x509" "encoding/pem" "fmt" "io/ioutil" "log" "net/http" "strings" "time" "github.com/go-fed/httpsig" ) func followInbox(inboxurl string) { matchset := re.FindStringSubmatch(inboxurl) if matchset == nil { logWarn("Unable to unregex request", inboxurl) return } inboxhostname := matchset[1] keyBytes, err := ioutil.ReadFile("keys/private.pem") if err != nil { log.Fatal(err) } pemBlock, _ := pem.Decode(keyBytes) if pemBlock == nil { log.Fatal("Invalid PEM format") } privateKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes) if err != nil { log.Fatal(err) } jsonRequest := fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://%[2]s/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://%[2]s/relay","cc":[],"id":"https://%[2]s/activities/bd0614f5-371d-4bd2-88b3-1ee12f7bf42a","object":"%[1]s","state":"pending","to":["%[1]s"],"type":"Follow"}`, inboxurl, settings.Hostname) //var jsonBytes []byte jsonBytes := []byte(jsonRequest) payload := bytes.NewReader(jsonBytes) prefs := []httpsig.Algorithm{httpsig.RSA_SHA256} digestAlgorithm := httpsig.DigestSha256 headers := []string{httpsig.RequestTarget, "date", "host"} signer, _, err := httpsig.NewSigner(prefs, digestAlgorithm, headers, httpsig.Signature, 0) if err != nil { log.Fatal(err.Error()) } req, err := http.NewRequest("POST", inboxurl, payload) if err != nil { log.Fatal(err.Error()) } if payload != nil { req.Header.Add("content-type", "application/json") } req.Header.Add("date", time.Now().UTC().Format(http.TimeFormat)) req.Header.Add("host", inboxhostname) keyID := "https://" + settings.Hostname + "/relay" err = signer.SignRequest(privateKey, keyID, req, jsonBytes) if err != nil { log.Fatal(err.Error()) } req.Header["Signature"][0] = strings.Replace(req.Header["Signature"][0], "algorithm=\"hs2019\"", "algorithm=\"rsa-sha256\"", 1) customTransport := http.DefaultTransport.(*http.Transport).Clone() customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} client := &http.Client{Timeout: 10 * time.Second, Transport: customTransport} // client := &http.Client{Timeout: 10 * time.Second} res, err := client.Do(req) if err != nil { log.Fatal(err) } defer res.Body.Close() }