Federated via graft
0

Configure Feed

Select the types of activity you want to include in your feed.

1// Package activitypub exposes graft's mirrored repos over ActivityPub: one 2// actor per series (e.g. @federation-x@graft.cyberwild.org), so anyone on 3// the fediverse can follow a repo and see its mirrored commits, issues, and 4// patches show up as posts. 5package activitypub 6 7import ( 8 "crypto/rand" 9 "crypto/rsa" 10 "crypto/x509" 11 "encoding/pem" 12 "fmt" 13) 14 15// GenerateKeyPair creates a new RSA-2048 keypair, PEM-encoded — RSA because 16// that's what HTTP Signatures (the scheme ActivityPub implementations like 17// Mastodon use to authenticate federated requests) expects in practice. 18func GenerateKeyPair() (privatePEM, publicPEM string, err error) { 19 key, err := rsa.GenerateKey(rand.Reader, 2048) 20 if err != nil { 21 return "", "", fmt.Errorf("generate rsa key: %w", err) 22 } 23 24 privBytes := x509.MarshalPKCS1PrivateKey(key) 25 priv := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: privBytes}) 26 27 pubBytes, err := x509.MarshalPKIXPublicKey(&key.PublicKey) 28 if err != nil { 29 return "", "", fmt.Errorf("marshal public key: %w", err) 30 } 31 pub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubBytes}) 32 33 return string(priv), string(pub), nil 34} 35 36// ParsePrivateKey decodes a PEM-encoded RSA private key, as stored via 37// GenerateKeyPair. 38func ParsePrivateKey(pemStr string) (*rsa.PrivateKey, error) { 39 block, _ := pem.Decode([]byte(pemStr)) 40 if block == nil { 41 return nil, fmt.Errorf("no PEM block found in private key") 42 } 43 return x509.ParsePKCS1PrivateKey(block.Bytes) 44}