mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-26 08:35:17 +00:00
144 lines
3.3 KiB
Go
144 lines
3.3 KiB
Go
package libp2pwebrtc
|
|
|
|
import (
|
|
"crypto"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
|
|
"github.com/multiformats/go-multihash"
|
|
)
|
|
|
|
// clientSDP describes an SDP format string which can be used
|
|
// to infer a client's SDP offer from the incoming STUN message.
|
|
// The fingerprint used to render a client SDP is arbitrary since
|
|
// it fingerprint verification is disabled in favour of a noise
|
|
// handshake. The max message size is fixed to 16384 bytes.
|
|
const clientSDP = `v=0
|
|
o=- 0 0 IN %[1]s %[2]s
|
|
s=-
|
|
c=IN %[1]s %[2]s
|
|
t=0 0
|
|
|
|
m=application %[3]d UDP/DTLS/SCTP webrtc-datachannel
|
|
a=mid:0
|
|
a=ice-options:ice2
|
|
a=ice-ufrag:%[4]s
|
|
a=ice-pwd:%[4]s
|
|
a=fingerprint:sha-256 ba:78:16:bf:8f:01:cf:ea:41:41:40:de:5d:ae:22:23:b0:03:61:a3:96:17:7a:9c:b4:10:ff:61:f2:00:15:ad
|
|
a=setup:actpass
|
|
a=sctp-port:5000
|
|
a=max-message-size:16384
|
|
`
|
|
|
|
func createClientSDP(addr *net.UDPAddr, ufrag string) string {
|
|
ipVersion := "IP4"
|
|
if addr.IP.To4() == nil {
|
|
ipVersion = "IP6"
|
|
}
|
|
return fmt.Sprintf(
|
|
clientSDP,
|
|
ipVersion,
|
|
addr.IP,
|
|
addr.Port,
|
|
ufrag,
|
|
)
|
|
}
|
|
|
|
// serverSDP defines an SDP format string used by a dialer
|
|
// to infer the SDP answer of a server based on the provided
|
|
// multiaddr, and the locally set ICE credentials. The max
|
|
// message size is fixed to 16384 bytes.
|
|
const serverSDP = `v=0
|
|
o=- 0 0 IN %[1]s %[2]s
|
|
s=-
|
|
t=0 0
|
|
a=ice-lite
|
|
m=application %[3]d UDP/DTLS/SCTP webrtc-datachannel
|
|
c=IN %[1]s %[2]s
|
|
a=mid:0
|
|
a=ice-options:ice2
|
|
a=ice-ufrag:%[4]s
|
|
a=ice-pwd:%[4]s
|
|
a=fingerprint:%[5]s
|
|
|
|
a=setup:passive
|
|
a=sctp-port:5000
|
|
a=max-message-size:16384
|
|
a=candidate:1 1 UDP 1 %[2]s %[3]d typ host
|
|
a=end-of-candidates
|
|
`
|
|
|
|
func createServerSDP(addr *net.UDPAddr, ufrag string, fingerprint multihash.DecodedMultihash) (string, error) {
|
|
ipVersion := "IP4"
|
|
if addr.IP.To4() == nil {
|
|
ipVersion = "IP6"
|
|
}
|
|
|
|
sdpString, err := getSupportedSDPString(fingerprint.Code)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var builder strings.Builder
|
|
builder.Grow(len(fingerprint.Digest)*3 + 8)
|
|
builder.WriteString(sdpString)
|
|
builder.WriteByte(' ')
|
|
builder.WriteString(encodeInterspersedHex(fingerprint.Digest))
|
|
fp := builder.String()
|
|
|
|
return fmt.Sprintf(
|
|
serverSDP,
|
|
ipVersion,
|
|
addr.IP,
|
|
addr.Port,
|
|
ufrag,
|
|
fp,
|
|
), nil
|
|
}
|
|
|
|
// getSupportedSDPHash converts a multihash code to the
|
|
// corresponding crypto.Hash for supported protocols. If a
|
|
// crypto.Hash cannot be found, it returns `(0, false)`
|
|
func getSupportedSDPHash(code uint64) (crypto.Hash, bool) {
|
|
switch code {
|
|
case multihash.MD5:
|
|
return crypto.MD5, true
|
|
case multihash.SHA1:
|
|
return crypto.SHA1, true
|
|
case multihash.SHA3_224:
|
|
return crypto.SHA3_224, true
|
|
case multihash.SHA2_256:
|
|
return crypto.SHA256, true
|
|
case multihash.SHA3_384:
|
|
return crypto.SHA3_384, true
|
|
case multihash.SHA2_512:
|
|
return crypto.SHA512, true
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|
|
|
|
// getSupportedSDPString converts a multihash code
|
|
// to a string format recognised by pion for fingerprint
|
|
// algorithms
|
|
func getSupportedSDPString(code uint64) (string, error) {
|
|
// values based on (cryto.Hash).String()
|
|
switch code {
|
|
case multihash.MD5:
|
|
return "md5", nil
|
|
case multihash.SHA1:
|
|
return "sha-1", nil
|
|
case multihash.SHA3_224:
|
|
return "sha3-224", nil
|
|
case multihash.SHA2_256:
|
|
return "sha-256", nil
|
|
case multihash.SHA3_384:
|
|
return "sha3-384", nil
|
|
case multihash.SHA2_512:
|
|
return "sha-512", nil
|
|
default:
|
|
return "", fmt.Errorf("unsupported hash code (%d)", code)
|
|
}
|
|
}
|