blob: 0c0cdc4aa1b1f163c013b3994826a82f0ba30cbf [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
15type args []interface{}
16
17// NewPrivateID returns a security.PrivateID implementation that wraps over 'wrapped' but
18// logs all operations that use the private key of wrapped to the auditor.
19func NewPrivateID(wrapped security.PrivateID, auditor Auditor) security.PrivateID {
20 return &auditingID{wrapped, auditor}
21}
22
23func (id *auditingID) Sign(message []byte) (security.Signature, error) {
24 sig, err := id.id.Sign(message)
25 // Do not save the signature itself.
26 if err = id.audit(err, "Sign", args{message}, nil); err != nil {
27 return security.Signature{}, err
28 }
29 return sig, nil
30}
31
Asim Shankar1c5b94a2014-09-05 16:36:12 -070032func (id *auditingID) PublicKey() security.PublicKey {
Asim Shankar1ac80612014-08-08 16:04:09 -070033 return id.id.PublicKey()
Asim Shankarf9f84bc2014-08-05 10:46:40 -070034}
35
36func (id *auditingID) PublicID() security.PublicID {
Asim Shankar1ac80612014-08-08 16:04:09 -070037 return id.id.PublicID()
Asim Shankarf9f84bc2014-08-05 10:46:40 -070038}
39
Ankurf044a8d2014-09-05 17:05:24 -070040func (id *auditingID) Bless(blessee security.PublicID, blessingName string, duration time.Duration, caveats []security.Caveat) (security.PublicID, error) {
Asim Shankarf9f84bc2014-08-05 10:46:40 -070041 blessed, err := id.id.Bless(blessee, blessingName, duration, caveats)
42 if err = id.audit(err, "Bless", args{blessee, blessingName, duration, caveats}, blessed); err != nil {
43 return nil, err
44 }
45 return blessed, nil
46}
47
48func (id *auditingID) Derive(publicID security.PublicID) (security.PrivateID, error) {
Asim Shankar1ac80612014-08-08 16:04:09 -070049 // No auditing for Derive. Two reasons:
50 // (1) This method is expected to go away (ataly@)
51 // (2) There is no operation on the private key here.
52 // However, operations on the Derived id do need to be audited.
Asim Shankarf9f84bc2014-08-05 10:46:40 -070053 derived, err := id.id.Derive(publicID)
Asim Shankar1ac80612014-08-08 16:04:09 -070054 if err != nil {
Asim Shankarf9f84bc2014-08-05 10:46:40 -070055 return nil, err
56 }
Asim Shankar1ac80612014-08-08 16:04:09 -070057 return NewPrivateID(derived, id.auditor), nil
Asim Shankarf9f84bc2014-08-05 10:46:40 -070058}
59
Ankurf044a8d2014-09-05 17:05:24 -070060func (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 -070061 d, err := id.id.MintDischarge(caveat, context, duration, caveats)
62 if err = id.audit(err, "MintDischarge", args{caveat, context, duration, caveats}, nil); err != nil {
63 return nil, err
64 }
65 return d, nil
66}
67
68func (id *auditingID) audit(err error, method string, args args, result interface{}) error {
69 if err != nil {
70 return err
71 }
Asim Shankar1ac80612014-08-08 16:04:09 -070072 entry := Entry{Method: method, Timestamp: time.Now()}
73 if len(args) > 0 {
74 entry.Arguments = []interface{}(args)
75 }
76 if result != nil {
77 entry.Results = []interface{}{result}
78 }
79 if err := id.auditor.Audit(entry); err != nil {
Asim Shankarf9f84bc2014-08-05 10:46:40 -070080 return fmt.Errorf("failed to audit call to %q: %v", method, err)
81 }
82 return nil
83}