ricochet-go/core/address.go

85 lines
1.8 KiB
Go

package core
import (
"crypto/rsa"
"errors"
"github.com/yawning/bulb/utils/pkcs1"
"strings"
)
// Conversion functions between ricochet addresses, onion hostnames, and 80-bit base32 encoded fingerprints.
// As used in this file, these are referred to as 'address', 'onion', and 'plain host' respectively.
func isBase32Valid(str string) bool {
for _, c := range []byte(str) {
if (c < 'a' || c > 'z') && (c < '2' || c > '7') {
return false
}
}
return true
}
func IsAddressValid(addr string) bool {
return len(addr) == 25 && strings.HasPrefix(addr, "ricochet:") && isBase32Valid(addr[9:])
}
func IsOnionValid(onion string) bool {
return len(onion) == 22 && strings.HasSuffix(onion, ".onion") && isBase32Valid(onion[0:16])
}
func IsPlainHostValid(host string) bool {
return len(host) == 16 && isBase32Valid(host)
}
func AddressFromOnion(onion string) (string, bool) {
if !IsOnionValid(onion) {
return "", false
}
return "ricochet:" + onion[0:16], true
}
func OnionFromAddress(addr string) (string, bool) {
if !IsAddressValid(addr) {
return "", false
}
return addr[9:] + ".onion", true
}
func OnionFromPlainHost(host string) (string, bool) {
if !IsPlainHostValid(host) {
return "", false
}
return host + ".onion", true
}
func PlainHostFromOnion(onion string) (string, bool) {
if !IsOnionValid(onion) {
return "", false
}
return onion[0:16], true
}
func AddressFromPlainHost(host string) (string, bool) {
if !IsPlainHostValid(host) {
return "", false
}
return "ricochet:" + host, true
}
func PlainHostFromAddress(host string) (string, bool) {
if !IsAddressValid(host) {
return "", false
}
return host[9:], true
}
func AddressFromKey(key *rsa.PublicKey) (string, error) {
addr, err := pkcs1.OnionAddr(key)
if err != nil {
return "", err
} else if addr == "" {
return "", errors.New("Invalid key")
}
return "ricochet:" + addr, nil
}