aboutsummaryrefslogtreecommitdiff
path: root/messages.go
blob: 26caeac40967774f6189a5eac427f4ebc2a20a7b (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
204
205
206
207
208
209
210
211
212
213
214
215
216
package acme

import (
	"fmt"
	"net"
	"time"

	"github.com/square/go-jose"
)

const (
	// LEV1 Let's Encrytpt V1
	LEV1 = `https://acme-v01.api.letsencrypt.org/directory`
	// LES Let's Encrypt Staging
	LES = `https://acme-staging.api.letsencrypt.org/directory`
)

// Directory ...
type Directory struct {
	NewReg     string `json:"new-reg"`
	RecoverReg string `json:"recover-reg"`
	NewAuthz   string `json:"new-authz"`
	NewCert    string `json:"new-cert"`
	RevokeCert string `json:"revoke-cert"`
}

// Registration Objects
type Registration struct {
	Resource       Resource         `json:"resource"` // new-reg
	Contact        Contacts         `json:"contact,omitempty"`
	Agreement      string           `json:"agreement,omitempty"`
	Authorizations string           `json:"authorizations,omitempty"`
	Certificates   string           `json:"certificates,omitempty"`
	ID             int              `json:"id,omitempty"`
	Key            *jose.JsonWebKey `json:"key,omitempty"`
	InitialIP      *net.IP          `json:"initialIp,omitempty"` // not in draft
	CreatedAt      *time.Time       `json:"createdAt,omitempty"`
}

// Authorization request
type Authorization struct {
	Resource     Resource    `json:"resource"` // new-authz
	Identifier   Identifier  `json:"identifier"`
	Status       Status      `json:"status,omitempty"` // e.g. valid
	Expires      *time.Time  `json:"expires,omitempty"`
	Challenges   []Challenge `json:"challenges,omitempty"`
	Combinations [][]int     `json:"combinations,omitempty"`
}

// Identifier ...
type Identifier struct {
	Type  IdentType `json:"type"`  // dns
	Value string    `json:"value"` // example.com
}

// Challege ...
type Challenge struct {
	Resource         Resource      `json:"resource"` // challenge
	Type             ChallengeType `json:"type"`
	Token            string        `json:"token,omitempty"`
	Status           Status        `json:"status,omitempty"` // e.g. valid
	URI              string        `json:"uri,omitempty"`
	Validated        *time.Time    `json:"validated,omitempty"`
	KeyAuthorization string        `json:"keyAuthorization,omitempty"`
	Err              *Problem      `json:"error,omitempty"`
	Solver           `json:"-"`
}

// Problem description
type Problem struct {
	Type     string `json:"type"`
	Detail   string `json:"detail"`
	Instance string `json:"instance"`
	Err      error  `json:"-"`
}

func (p Problem) Error() string {
	return p.Detail
}

// Status of request
type Status int

// Statuses
const (
	StatusUnknown Status = iota + 1
	StatusPending
	StatusProcessing
	StatusValid
	StatusInvalid
	StatusRevoked
)

var status = map[Status]string{
	StatusUnknown:    "unknown",
	StatusPending:    "pending",
	StatusProcessing: "processing",
	StatusValid:      "valid",
	StatusInvalid:    "invalid",
	StatusRevoked:    "revoked",
}

// UnmarshalText implemets json interface for status decoding
func (s *Status) UnmarshalText(b []byte) error {
	for k, v := range status {
		if v == string(b) {
			*s = k
			return nil
		}
	}
	return fmt.Errorf("unknown status %v", string(b))
}

func (s Status) String() string {
	return status[s]
}

type Resource int

const (
	ResNewReg Resource = iota + 1
	ResRecoverReg
	ResNewAuthz
	ResNewCert
	ResRevokeCert
	ResReg
	ResAuthz
	ResChallenge
	ResCert
)

var resources = map[Resource]string{
	ResNewReg:     "new-reg",
	ResRecoverReg: "recover-reg",
	ResNewAuthz:   "new-authz",
	ResNewCert:    "new-cert",
	ResRevokeCert: "revoke-cert",
	ResReg:        "reg",
	ResAuthz:      "authz",
	ResChallenge:  "challenge",
	ResCert:       "cert",
}

func (r Resource) String() string {
	return resources[r]
}

// MarshalText implements text encoding marshaller
func (r Resource) MarshalText() ([]byte, error) {
	return []byte(r.String()), nil
}

type IdentType int

const IdentDNS IdentType = iota + 1

var identTypes = map[IdentType]string{
	IdentDNS: "dns",
}

func (i IdentType) String() string {
	return identTypes[i]
}

func (i IdentType) MarshalText() ([]byte, error) {
	return []byte(i.String()), nil
}

func (i *IdentType) UnmarshalText(b []byte) error {
	for k, v := range identTypes {
		if v == string(b) {
			*i = k
			return nil
		}
	}
	return fmt.Errorf("unknown type %v", string(b))
}

type ChallengeType int

const (
	ChallengeHTTP ChallengeType = iota + 1
	ChallengeTLS
	ChallengePOP
	ChallengeDNS
)

var challenges = map[ChallengeType]string{
	ChallengeHTTP: "http-01",
	ChallengeTLS:  "tls-sni-01",
	ChallengePOP:  "proofOfPossession-01",
	ChallengeDNS:  "dns-01",
}

func (c ChallengeType) String() string {
	return challenges[c]
}

func (c ChallengeType) MarshalText() ([]byte, error) {
	return []byte(c.String()), nil
}

func (c *ChallengeType) UnmarshalText(b []byte) error {
	for k, v := range challenges {
		if v == string(b) {
			*c = k
			return nil
		}
	}
	return fmt.Errorf("unknown challenge %v", string(b))
}

type CSR struct {
	Resource Resource `json:"resource"` // new-cert
	CSR      string   `json:"csr"`
}