1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package server
18
19 import (
20 "crypto"
21 "fmt"
22 "net/http"
23
24 "github.com/sassoftware/relic/internal/signinit"
25 "github.com/sassoftware/relic/lib/readercounter"
26 "github.com/sassoftware/relic/lib/x509tools"
27 "github.com/sassoftware/relic/signers"
28 )
29
30 const defaultHash = crypto.SHA256
31
32 func (s *Server) serveSign(request *http.Request, writer http.ResponseWriter) (res Response, err error) {
33 if request.Method != "POST" {
34 return ErrorResponse(http.StatusMethodNotAllowed), nil
35 }
36
37 query := request.URL.Query()
38 keyName := query.Get("key")
39 if keyName == "" {
40 return StringResponse(http.StatusBadRequest, "'key' query parameter is required"), nil
41 }
42 filename := query.Get("filename")
43 if filename == "" {
44 return StringResponse(http.StatusBadRequest, "'filename' query parameter is required"), nil
45 }
46 sigType := query.Get("sigtype")
47 keyConf := s.CheckKeyAccess(request, keyName)
48 if keyConf == nil {
49 s.Logr(request, "access denied to key %s\n", keyName)
50 return AccessDeniedResponse, nil
51 }
52 mod := signers.ByName(sigType)
53 if mod == nil {
54 s.Logr(request, "error: unknown sigtype: sigtype=%s key=%s", sigType, keyName)
55 return StringResponse(http.StatusBadRequest, "unknown sigtype"), nil
56 }
57 hash := defaultHash
58 if digest := request.URL.Query().Get("digest"); digest != "" {
59 hash = x509tools.HashByName(digest)
60 if hash == 0 {
61 s.Logr(request, "error: unknown digest %s", digest)
62 return StringResponse(http.StatusBadRequest, "unknown digest"), nil
63 }
64 }
65 flags, err := mod.FlagsFromQuery(query)
66 if err != nil {
67 s.Logr(request, "error: parsing arguments: %s", err)
68 return StringResponse(http.StatusBadRequest, "invalid parameters"), nil
69 }
70
71 tok := s.tokens[keyConf.Token]
72 if tok == nil {
73 return nil, fmt.Errorf("missing token \"%s\" for key \"%s\"", keyConf.Token, keyName)
74 }
75 cert, opts, err := signinit.Init(request.Context(), mod, tok, keyName, hash, flags)
76 if err != nil {
77 return nil, err
78 }
79 opts.Audit.Attributes["client.ip"] = GetClientIP(request)
80 opts.Audit.Attributes["client.name"] = GetClientName(request)
81 opts.Audit.Attributes["client.dn"] = GetClientDN(request)
82 opts.Audit.Attributes["client.filename"] = filename
83
84 counter := readercounter.New(request.Body)
85 blob, err := mod.Sign(counter, cert, *opts)
86 if err != nil {
87 return nil, err
88 }
89 opts.Audit.Attributes["perf.size.in"] = counter.N
90 opts.Audit.Attributes["perf.size.patch"] = len(blob)
91 var extra string
92 if mod.FormatLog != nil {
93 extra = mod.FormatLog(opts.Audit)
94 }
95 if extra != "" {
96 extra = " " + extra
97 }
98 if err := signinit.PublishAudit(opts.Audit); err != nil {
99 return nil, err
100 }
101 s.Logr(request, "Signed package: filename=%s key=%s%s", filename, keyConf.Name(), extra)
102 return BytesResponse(blob, opts.Audit.GetMimeType()), nil
103 }
104
View as plain text