This repository has been archived by the owner on Sep 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
finalize.go
117 lines (101 loc) · 2.9 KB
/
finalize.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
package finalize
import (
"encoding/json"
"flag"
"net/http"
"github.com/abiosoft/ishell"
"github.com/cpu/acmeshell/acme/resources"
"github.com/cpu/acmeshell/shell/commands"
)
const (
longHelp = `TODO(@cpu): Write longHelp for finalize cmd`
)
func init() {
commands.RegisterCommand(
&ishell.Cmd{
Name: "finalize",
Aliases: []string{"finalizeOrder"},
Help: "Finalize an ACME order with a CSR",
LongHelp: longHelp,
Func: finalizeHandler,
},
nil)
}
type finalizeOptions struct {
csr string
keyID string
commonName string
orderIndex int
}
func finalizeHandler(c *ishell.Context) {
opts := finalizeOptions{}
finalizeFlags := flag.NewFlagSet("finalize", flag.ContinueOnError)
finalizeFlags.StringVar(&opts.csr, "csr", "", "base64url encoded CSR")
finalizeFlags.StringVar(&opts.keyID, "keyID", "", "keyID to use for generating a CSR")
finalizeFlags.StringVar(&opts.commonName, "cn", "", "subject common name (CN) for generated CSR")
finalizeFlags.IntVar(&opts.orderIndex, "order", -1, "index of existing order")
leftovers, err := commands.ParseFlagSetArgs(c.Args, finalizeFlags)
if err != nil {
return
}
if opts.csr != "" && opts.keyID != "" {
c.Printf("finalize: -csr and -keyID are mutually exclusive\n")
return
}
if opts.csr != "" && opts.commonName != "" {
c.Printf("finalize: -csr and -cn are mutually exclusive\n")
return
}
client := commands.GetClient(c)
targetURL, err := commands.FindOrderURL(c, leftovers, opts.orderIndex)
if err != nil {
c.Printf("finalize: error getting order URL: %v\n", err)
return
}
order := &resources.Order{
ID: targetURL,
}
err = client.UpdateOrder(order)
if err != nil {
c.Printf("finalize: error getting order: %s\n", err.Error())
return
}
var b64csr string
if opts.csr != "" {
b64csr = opts.csr
} else {
names := make([]string, len(order.Identifiers))
for i, ident := range order.Identifiers {
names[i] = ident.Value
}
csr, _, err := client.CSR(opts.commonName, names, opts.keyID)
if err != nil {
c.Printf("finalize: error creating csr: %s\n", err.Error())
return
}
b64csr = string(csr)
}
finalizeRequest := struct {
CSR string
}{
CSR: b64csr,
}
finalizeRequestJSON, _ := json.Marshal(&finalizeRequest)
signResult, err := client.Sign(order.Finalize, finalizeRequestJSON, nil)
if err != nil {
c.Printf("finalize: failed to sign finalize POST body: %s\n", err.Error())
return
}
resp, err := client.PostURL(order.Finalize, signResult.SerializedJWS)
if err != nil {
c.Printf("finalize: failed to POST order finalization URL %q: %v\n", order.Finalize, err)
return
}
respOb := resp.Response
if respOb.StatusCode != http.StatusOK {
c.Printf("finalize: failed to POST order finalization URL %q . Status code: %d\n", order.Finalize, respOb.StatusCode)
c.Printf("finalize: response body: %s\n", resp.RespBody)
return
}
c.Printf("order %q finalization requested\n", order.ID)
}