blob: b251ecc987f7ef58c30c55cf3d55e125854026c0 [file] [log] [blame]
Asim Shankardc150cd2014-08-08 10:59:39 -07001package audit
Asim Shankarf9f84bc2014-08-05 10:46:40 -07002
3import (
Asim Shankarf9f84bc2014-08-05 10:46:40 -07004 "fmt"
5 "time"
6
Jiri Simsa519c5072014-09-17 21:37:57 -07007 "veyron.io/veyron/veyron2/security"
Asim Shankarf9f84bc2014-08-05 10:46:40 -07008)
9
10type auditingID struct {
11 id security.PrivateID
12 auditor Auditor
13}
14
Asim Shankarf9f84bc2014-08-05 10:46:40 -070015// NewPrivateID returns a security.PrivateID implementation that wraps over 'wrapped' but
16// logs all operations that use the private key of wrapped to the auditor.
17func NewPrivateID(wrapped security.PrivateID, auditor Auditor) security.PrivateID {
18 return &auditingID{wrapped, auditor}
19}
20
21func (id *auditingID) Sign(message []byte) (security.Signature, error) {
22 sig, err := id.id.Sign(message)
23 // Do not save the signature itself.
24 if err = id.audit(err, "Sign", args{message}, nil); err != nil {
25 return security.Signature{}, err
26 }
27 return sig, nil
28}
29
Asim Shankar1c5b94a2014-09-05 16:36:12 -070030func (id *auditingID) PublicKey() security.PublicKey {
Asim Shankar1ac80612014-08-08 16:04:09 -070031 return id.id.PublicKey()
Asim Shankarf9f84bc2014-08-05 10:46:40 -070032}
33
34func (id *auditingID) PublicID() security.PublicID {
Asim Shankar1ac80612014-08-08 16:04:09 -070035 return id.id.PublicID()
Asim Shankarf9f84bc2014-08-05 10:46:40 -070036}
37
Ankurf044a8d2014-09-05 17:05:24 -070038func (id *auditingID) Bless(blessee security.PublicID, blessingName string, duration time.Duration, caveats []security.Caveat) (security.PublicID, error) {
Asim Shankarf9f84bc2014-08-05 10:46:40 -070039 blessed, err := id.id.Bless(blessee, blessingName, duration, caveats)
40 if err = id.audit(err, "Bless", args{blessee, blessingName, duration, caveats}, blessed); err != nil {
41 return nil, err
42 }
43 return blessed, nil
44}
45
46func (id *auditingID) Derive(publicID security.PublicID) (security.PrivateID, error) {
Asim Shankar1ac80612014-08-08 16:04:09 -070047 // No auditing for Derive. Two reasons:
48 // (1) This method is expected to go away (ataly@)
49 // (2) There is no operation on the private key here.
50 // However, operations on the Derived id do need to be audited.
Asim Shankarf9f84bc2014-08-05 10:46:40 -070051 derived, err := id.id.Derive(publicID)
Asim Shankar1ac80612014-08-08 16:04:09 -070052 if err != nil {
Asim Shankarf9f84bc2014-08-05 10:46:40 -070053 return nil, err
54 }
Asim Shankar1ac80612014-08-08 16:04:09 -070055 return NewPrivateID(derived, id.auditor), nil
Asim Shankarf9f84bc2014-08-05 10:46:40 -070056}
57
Ankurf044a8d2014-09-05 17:05:24 -070058func (id *auditingID) MintDischarge(caveat security.ThirdPartyCaveat, context security.Context, duration time.Duration, caveats []security.Caveat) (security.Discharge, error) {
Asim Shankarf9f84bc2014-08-05 10:46:40 -070059 d, err := id.id.MintDischarge(caveat, context, duration, caveats)
60 if err = id.audit(err, "MintDischarge", args{caveat, context, duration, caveats}, nil); err != nil {
61 return nil, err
62 }
63 return d, nil
64}
65
66func (id *auditingID) audit(err error, method string, args args, result interface{}) error {
67 if err != nil {
68 return err
69 }
Asim Shankar1ac80612014-08-08 16:04:09 -070070 entry := Entry{Method: method, Timestamp: time.Now()}
71 if len(args) > 0 {
72 entry.Arguments = []interface{}(args)
73 }
74 if result != nil {
75 entry.Results = []interface{}{result}
76 }
77 if err := id.auditor.Audit(entry); err != nil {
Asim Shankarf9f84bc2014-08-05 10:46:40 -070078 return fmt.Errorf("failed to audit call to %q: %v", method, err)
79 }
80 return nil
81}