forked from letsencrypt/boulder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
model.go
200 lines (185 loc) · 5.29 KB
/
model.go
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
// Copyright 2015 ISRG. All rights reserved
// 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 sa
import (
"encoding/json"
"fmt"
"math"
"net"
"time"
jose "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
"github.com/letsencrypt/boulder/core"
"github.com/letsencrypt/boulder/probs"
)
var mediumBlobSize = int(math.Pow(2, 24))
type issuedNameModel struct {
ID int64 `db:"id"`
ReversedName string `db:"reversedName"`
NotBefore time.Time `db:"notBefore"`
Serial string `db:"serial"`
}
// regModel is the description of a core.Registration in the database.
type regModel struct {
ID int64 `db:"id"`
Key []byte `db:"jwk"`
KeySHA256 string `db:"jwk_sha256"`
Contact []*core.AcmeURL `db:"contact"`
Agreement string `db:"agreement"`
// InitialIP is stored as sixteen binary bytes, regardless of whether it
// represents a v4 or v6 IP address.
InitialIP []byte `db:"initialIp"`
CreatedAt time.Time `db:"createdAt"`
LockCol int64
}
// challModel is the description of a core.Challenge in the database
//
// The Validation field is a stub; the column is only there for backward compatibility.
type challModel struct {
ID int64 `db:"id"`
AuthorizationID string `db:"authorizationID"`
Type string `db:"type"`
Status core.AcmeStatus `db:"status"`
Error []byte `db:"error"`
Validated *time.Time `db:"validated"`
Token string `db:"token"`
KeyAuthorization string `db:"keyAuthorization"`
ValidationRecord []byte `db:"validationRecord"`
AccountKey []byte `db:"accountKey"`
LockCol int64
// obsoleteTLS is obsoleted. Only used for simpleHTTP and simpleHTTP is
// dead. Only still here because gorp complains if its gone and locks up if
// its private.
ObsoleteTLS *bool `db:"tls"`
}
// newReg creates a reg model object from a core.Registration
func registrationToModel(r *core.Registration) (*regModel, error) {
key, err := json.Marshal(r.Key)
if err != nil {
return nil, err
}
sha, err := core.KeyDigest(r.Key)
if err != nil {
return nil, err
}
if r.InitialIP == nil {
return nil, fmt.Errorf("initialIP was nil")
}
rm := ®Model{
ID: r.ID,
Key: key,
KeySHA256: sha,
Contact: r.Contact,
Agreement: r.Agreement,
InitialIP: []byte(r.InitialIP.To16()),
CreatedAt: r.CreatedAt,
}
return rm, nil
}
func modelToRegistration(rm *regModel) (core.Registration, error) {
k := &jose.JsonWebKey{}
err := json.Unmarshal(rm.Key, k)
if err != nil {
err = fmt.Errorf("unable to unmarshal JsonWebKey in db: %s", err)
return core.Registration{}, err
}
r := core.Registration{
ID: rm.ID,
Key: *k,
Contact: rm.Contact,
Agreement: rm.Agreement,
InitialIP: net.IP(rm.InitialIP),
CreatedAt: rm.CreatedAt,
}
return r, nil
}
func challengeToModel(c *core.Challenge, authID string) (*challModel, error) {
cm := challModel{
ID: c.ID,
AuthorizationID: authID,
Type: c.Type,
Status: c.Status,
Validated: c.Validated,
Token: c.Token,
}
if c.KeyAuthorization != nil {
kaString := c.KeyAuthorization.String()
if len(kaString) > 255 {
return nil, fmt.Errorf("Key authorization is too large to store in the database")
}
cm.KeyAuthorization = kaString
}
if c.Error != nil {
errJSON, err := json.Marshal(c.Error)
if err != nil {
return nil, err
}
if len(errJSON) > mediumBlobSize {
return nil, fmt.Errorf("Error object is too large to store in the database")
}
cm.Error = errJSON
}
if len(c.ValidationRecord) > 0 {
vrJSON, err := json.Marshal(c.ValidationRecord)
if err != nil {
return nil, err
}
if len(vrJSON) > mediumBlobSize {
return nil, fmt.Errorf("Validation Record object is too large to store in the database")
}
cm.ValidationRecord = vrJSON
}
if c.AccountKey != nil {
akJSON, err := json.Marshal(c.AccountKey)
if err != nil {
return nil, err
}
if len(akJSON) > mediumBlobSize {
return nil, fmt.Errorf("Account key object is too large to store in the database")
}
cm.AccountKey = akJSON
}
return &cm, nil
}
func modelToChallenge(cm *challModel) (core.Challenge, error) {
c := core.Challenge{
ID: cm.ID,
Type: cm.Type,
Status: cm.Status,
Validated: cm.Validated,
Token: cm.Token,
}
if len(cm.KeyAuthorization) > 0 {
ka, err := core.NewKeyAuthorizationFromString(cm.KeyAuthorization)
if err != nil {
return core.Challenge{}, err
}
c.KeyAuthorization = &ka
}
if len(cm.Error) > 0 {
var problem probs.ProblemDetails
err := json.Unmarshal(cm.Error, &problem)
if err != nil {
return core.Challenge{}, err
}
c.Error = &problem
}
if len(cm.ValidationRecord) > 0 {
var vr []core.ValidationRecord
err := json.Unmarshal(cm.ValidationRecord, &vr)
if err != nil {
return core.Challenge{}, err
}
c.ValidationRecord = vr
}
if len(cm.AccountKey) > 0 {
var ak jose.JsonWebKey
err := json.Unmarshal(cm.AccountKey, &ak)
if err != nil {
return core.Challenge{}, err
}
c.AccountKey = &ak
}
return c, nil
}