Asim Shankar | dc150cd | 2014-08-08 10:59:39 -0700 | [diff] [blame] | 1 | package audit |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 2 | |
| 3 | import ( |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 4 | "fmt" |
| 5 | "time" |
| 6 | |
Jiri Simsa | 519c507 | 2014-09-17 21:37:57 -0700 | [diff] [blame] | 7 | "veyron.io/veyron/veyron2/security" |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 8 | ) |
| 9 | |
| 10 | type auditingID struct { |
| 11 | id security.PrivateID |
| 12 | auditor Auditor |
| 13 | } |
| 14 | |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 15 | // 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. |
| 17 | func NewPrivateID(wrapped security.PrivateID, auditor Auditor) security.PrivateID { |
| 18 | return &auditingID{wrapped, auditor} |
| 19 | } |
| 20 | |
| 21 | func (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 Shankar | 1c5b94a | 2014-09-05 16:36:12 -0700 | [diff] [blame] | 30 | func (id *auditingID) PublicKey() security.PublicKey { |
Asim Shankar | 1ac8061 | 2014-08-08 16:04:09 -0700 | [diff] [blame] | 31 | return id.id.PublicKey() |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 32 | } |
| 33 | |
| 34 | func (id *auditingID) PublicID() security.PublicID { |
Asim Shankar | 1ac8061 | 2014-08-08 16:04:09 -0700 | [diff] [blame] | 35 | return id.id.PublicID() |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 36 | } |
| 37 | |
Ankur | f044a8d | 2014-09-05 17:05:24 -0700 | [diff] [blame] | 38 | func (id *auditingID) Bless(blessee security.PublicID, blessingName string, duration time.Duration, caveats []security.Caveat) (security.PublicID, error) { |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 39 | 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 | |
| 46 | func (id *auditingID) Derive(publicID security.PublicID) (security.PrivateID, error) { |
Asim Shankar | 1ac8061 | 2014-08-08 16:04:09 -0700 | [diff] [blame] | 47 | // 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 Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 51 | derived, err := id.id.Derive(publicID) |
Asim Shankar | 1ac8061 | 2014-08-08 16:04:09 -0700 | [diff] [blame] | 52 | if err != nil { |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 53 | return nil, err |
| 54 | } |
Asim Shankar | 1ac8061 | 2014-08-08 16:04:09 -0700 | [diff] [blame] | 55 | return NewPrivateID(derived, id.auditor), nil |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 56 | } |
| 57 | |
Ankur | f044a8d | 2014-09-05 17:05:24 -0700 | [diff] [blame] | 58 | func (id *auditingID) MintDischarge(caveat security.ThirdPartyCaveat, context security.Context, duration time.Duration, caveats []security.Caveat) (security.Discharge, error) { |
Asim Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 59 | 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 | |
| 66 | func (id *auditingID) audit(err error, method string, args args, result interface{}) error { |
| 67 | if err != nil { |
| 68 | return err |
| 69 | } |
Asim Shankar | 1ac8061 | 2014-08-08 16:04:09 -0700 | [diff] [blame] | 70 | 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 Shankar | f9f84bc | 2014-08-05 10:46:40 -0700 | [diff] [blame] | 78 | return fmt.Errorf("failed to audit call to %q: %v", method, err) |
| 79 | } |
| 80 | return nil |
| 81 | } |