summary refs log tree commit diff
path: root/vendor/maunium.net/go/mautrix/id/crypto.go
blob: 355a84a81475df5fa6933b413e337492537488a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// Copyright (c) 2020 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package id

import (
	"encoding/base64"
	"fmt"
	"strings"

	"go.mau.fi/util/random"
)

// OlmMsgType is an Olm message type
type OlmMsgType int

const (
	OlmMsgTypePreKey OlmMsgType = 0
	OlmMsgTypeMsg    OlmMsgType = 1
)

// Algorithm is a Matrix message encryption algorithm.
// https://spec.matrix.org/v1.2/client-server-api/#messaging-algorithm-names
type Algorithm string

const (
	AlgorithmOlmV1    Algorithm = "m.olm.v1.curve25519-aes-sha2"
	AlgorithmMegolmV1 Algorithm = "m.megolm.v1.aes-sha2"
)

type KeyAlgorithm string

const (
	KeyAlgorithmCurve25519       KeyAlgorithm = "curve25519"
	KeyAlgorithmEd25519          KeyAlgorithm = "ed25519"
	KeyAlgorithmSignedCurve25519 KeyAlgorithm = "signed_curve25519"
)

type CrossSigningUsage string

const (
	XSUsageMaster      CrossSigningUsage = "master"
	XSUsageSelfSigning CrossSigningUsage = "self_signing"
	XSUsageUserSigning CrossSigningUsage = "user_signing"
)

type KeyBackupAlgorithm string

const (
	KeyBackupAlgorithmMegolmBackupV1 KeyBackupAlgorithm = "m.megolm_backup.v1.curve25519-aes-sha2"
)

// BackupVersion is an arbitrary string that identifies a server side key backup.
type KeyBackupVersion string

func (version KeyBackupVersion) String() string {
	return string(version)
}

// A SessionID is an arbitrary string that identifies an Olm or Megolm session.
type SessionID string

func (sessionID SessionID) String() string {
	return string(sessionID)
}

// Ed25519 is the base64 representation of an Ed25519 public key
type Ed25519 string
type SigningKey = Ed25519

func (ed25519 Ed25519) String() string {
	return string(ed25519)
}

func (ed25519 Ed25519) Bytes() []byte {
	val, _ := base64.RawStdEncoding.DecodeString(string(ed25519))
	// TODO handle errors
	return val
}

func (ed25519 Ed25519) Fingerprint() string {
	spacedSigningKey := make([]byte, len(ed25519)+(len(ed25519)-1)/4)
	var ptr = 0
	for i, chr := range ed25519 {
		spacedSigningKey[ptr] = byte(chr)
		ptr++
		if i%4 == 3 {
			spacedSigningKey[ptr] = ' '
			ptr++
		}
	}
	return string(spacedSigningKey)
}

// Curve25519 is the base64 representation of an Curve25519 public key
type Curve25519 string
type SenderKey = Curve25519
type IdentityKey = Curve25519

func (curve25519 Curve25519) String() string {
	return string(curve25519)
}

func (curve25519 Curve25519) Bytes() []byte {
	val, _ := base64.RawStdEncoding.DecodeString(string(curve25519))
	// TODO handle errors
	return val
}

// A DeviceID is an arbitrary string that references a specific device.
type DeviceID string

func (deviceID DeviceID) String() string {
	return string(deviceID)
}

// A DeviceKeyID is a string formatted as <algorithm>:<device_id> that is used as the key in deviceid-key mappings.
type DeviceKeyID string

func NewDeviceKeyID(algorithm KeyAlgorithm, deviceID DeviceID) DeviceKeyID {
	return DeviceKeyID(fmt.Sprintf("%s:%s", algorithm, deviceID))
}

func (deviceKeyID DeviceKeyID) String() string {
	return string(deviceKeyID)
}

func (deviceKeyID DeviceKeyID) Parse() (Algorithm, DeviceID) {
	index := strings.IndexRune(string(deviceKeyID), ':')
	if index < 0 || len(deviceKeyID) <= index+1 {
		return "", ""
	}
	return Algorithm(deviceKeyID[:index]), DeviceID(deviceKeyID[index+1:])
}

// A KeyID a string formatted as <keyalgorithm>:<key_id> that is used as the key in one-time-key mappings.
type KeyID string

func NewKeyID(algorithm KeyAlgorithm, keyID string) KeyID {
	return KeyID(fmt.Sprintf("%s:%s", algorithm, keyID))
}

func (keyID KeyID) String() string {
	return string(keyID)
}

func (keyID KeyID) Parse() (KeyAlgorithm, string) {
	index := strings.IndexRune(string(keyID), ':')
	if index < 0 || len(keyID) <= index+1 {
		return "", ""
	}
	return KeyAlgorithm(keyID[:index]), string(keyID[index+1:])
}

// Device contains the identity details of a device and some additional info.
type Device struct {
	UserID      UserID
	DeviceID    DeviceID
	IdentityKey Curve25519
	SigningKey  Ed25519

	Trust   TrustState
	Deleted bool
	Name    string
}

func (device *Device) Fingerprint() string {
	return device.SigningKey.Fingerprint()
}

type CrossSigningKey struct {
	Key   Ed25519
	First Ed25519
}

// Secret storage keys
type Secret string

func (s Secret) String() string {
	return string(s)
}

const (
	SecretXSMaster       Secret = "m.cross_signing.master"
	SecretXSSelfSigning  Secret = "m.cross_signing.self_signing"
	SecretXSUserSigning  Secret = "m.cross_signing.user_signing"
	SecretMegolmBackupV1 Secret = "m.megolm_backup.v1"
)

// VerificationTransactionID is a unique identifier for a verification
// transaction.
type VerificationTransactionID string

func NewVerificationTransactionID() VerificationTransactionID {
	return VerificationTransactionID(random.String(32))
}

func (t VerificationTransactionID) String() string {
	return string(t)
}