| OLD | NEW |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package certconfig | 5 package certconfig |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "bytes" | 8 "bytes" |
| 9 "crypto/x509" | 9 "crypto/x509" |
| 10 "encoding/gob" | 10 "encoding/gob" |
| 11 "time" | 11 "time" |
| 12 | 12 |
| 13 "github.com/golang/protobuf/proto" | 13 "github.com/golang/protobuf/proto" |
| 14 "golang.org/x/net/context" | 14 "golang.org/x/net/context" |
| 15 | 15 |
| 16 ds "github.com/luci/gae/service/datastore" | 16 ds "github.com/luci/gae/service/datastore" |
| 17 "github.com/luci/luci-go/common/clock" | 17 "github.com/luci/luci-go/common/clock" |
| 18 "github.com/luci/luci-go/common/data/caching/lazyslot" | 18 "github.com/luci/luci-go/common/data/caching/lazyslot" |
| 19 "github.com/luci/luci-go/common/data/caching/proccache" | 19 "github.com/luci/luci-go/common/data/caching/proccache" |
| 20 » "github.com/luci/luci-go/common/errors" | 20 » "github.com/luci/luci-go/common/retry" |
| 21 | 21 |
| 22 "github.com/luci/luci-go/tokenserver/api/admin/v1" | 22 "github.com/luci/luci-go/tokenserver/api/admin/v1" |
| 23 ) | 23 ) |
| 24 | 24 |
| 25 // CA defines one trusted Certificate Authority (imported from config). | 25 // CA defines one trusted Certificate Authority (imported from config). |
| 26 // | 26 // |
| 27 // Entity key is CA Common Name (that must match what's is in the certificate). | 27 // Entity key is CA Common Name (that must match what's is in the certificate). |
| 28 // Certificate issuer (and the certificate signature) is ignored. Usually, the | 28 // Certificate issuer (and the certificate signature) is ignored. Usually, the |
| 29 // certificates here will be self-signed. | 29 // certificates here will be self-signed. |
| 30 // | 30 // |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 return nil, err | 69 return nil, err |
| 70 } | 70 } |
| 71 return msg, nil | 71 return msg, nil |
| 72 } | 72 } |
| 73 | 73 |
| 74 // ListCAs returns names of all currently active CAs, in no particular order. | 74 // ListCAs returns names of all currently active CAs, in no particular order. |
| 75 func ListCAs(c context.Context) ([]string, error) { | 75 func ListCAs(c context.Context) ([]string, error) { |
| 76 keys := []*ds.Key{} | 76 keys := []*ds.Key{} |
| 77 q := ds.NewQuery("CA").Eq("Removed", false).KeysOnly(true) | 77 q := ds.NewQuery("CA").Eq("Removed", false).KeysOnly(true) |
| 78 if err := ds.GetAll(c, q, &keys); err != nil { | 78 if err := ds.GetAll(c, q, &keys); err != nil { |
| 79 » » return nil, errors.WrapTransient(err) | 79 » » return nil, retry.Tag.Apply(err) |
| 80 } | 80 } |
| 81 names := make([]string, len(keys)) | 81 names := make([]string, len(keys)) |
| 82 for i, key := range keys { | 82 for i, key := range keys { |
| 83 names[i] = key.StringID() | 83 names[i] = key.StringID() |
| 84 } | 84 } |
| 85 return names, nil | 85 return names, nil |
| 86 } | 86 } |
| 87 | 87 |
| 88 // CAUniqueIDToCNMap is a singleton entity that stores a mapping between CA's | 88 // CAUniqueIDToCNMap is a singleton entity that stores a mapping between CA's |
| 89 // unique_id (specified in config) and its Common Name. | 89 // unique_id (specified in config) and its Common Name. |
| 90 // | 90 // |
| 91 // It's loaded in memory in full and kept cached there (for 1 min). | 91 // It's loaded in memory in full and kept cached there (for 1 min). |
| 92 // See GetCAByUniqueID below. | 92 // See GetCAByUniqueID below. |
| 93 type CAUniqueIDToCNMap struct { | 93 type CAUniqueIDToCNMap struct { |
| 94 _id int64 `gae:"$id,1"` | 94 _id int64 `gae:"$id,1"` |
| 95 | 95 |
| 96 GobEncodedMap []byte `gae:",noindex"` // gob-encoded map[int64]string | 96 GobEncodedMap []byte `gae:",noindex"` // gob-encoded map[int64]string |
| 97 } | 97 } |
| 98 | 98 |
| 99 // StoreCAUniqueIDToCNMap overwrites CAUniqueIDToCNMap with new content. | 99 // StoreCAUniqueIDToCNMap overwrites CAUniqueIDToCNMap with new content. |
| 100 func StoreCAUniqueIDToCNMap(c context.Context, mapping map[int64]string) error { | 100 func StoreCAUniqueIDToCNMap(c context.Context, mapping map[int64]string) error { |
| 101 buf := bytes.Buffer{} | 101 buf := bytes.Buffer{} |
| 102 enc := gob.NewEncoder(&buf) | 102 enc := gob.NewEncoder(&buf) |
| 103 if err := enc.Encode(mapping); err != nil { | 103 if err := enc.Encode(mapping); err != nil { |
| 104 return err | 104 return err |
| 105 } | 105 } |
| 106 // Note that in practice 'mapping' is usually very small, so we are not | 106 // Note that in practice 'mapping' is usually very small, so we are not |
| 107 // concerned about 1MB entity size limit. | 107 // concerned about 1MB entity size limit. |
| 108 » return errors.WrapTransient(ds.Put(c, &CAUniqueIDToCNMap{ | 108 » return retry.Tag.Apply(ds.Put(c, &CAUniqueIDToCNMap{ |
| 109 GobEncodedMap: buf.Bytes(), | 109 GobEncodedMap: buf.Bytes(), |
| 110 })) | 110 })) |
| 111 } | 111 } |
| 112 | 112 |
| 113 // LoadCAUniqueIDToCNMap loads CAUniqueIDToCNMap from the datastore. | 113 // LoadCAUniqueIDToCNMap loads CAUniqueIDToCNMap from the datastore. |
| 114 func LoadCAUniqueIDToCNMap(c context.Context) (map[int64]string, error) { | 114 func LoadCAUniqueIDToCNMap(c context.Context) (map[int64]string, error) { |
| 115 ent := CAUniqueIDToCNMap{} | 115 ent := CAUniqueIDToCNMap{} |
| 116 switch err := ds.Get(c, &ent); { | 116 switch err := ds.Get(c, &ent); { |
| 117 case err == ds.ErrNoSuchEntity: | 117 case err == ds.ErrNoSuchEntity: |
| 118 return nil, nil | 118 return nil, nil |
| 119 case err != nil: | 119 case err != nil: |
| 120 » » return nil, errors.WrapTransient(err) | 120 » » return nil, retry.Tag.Apply(err) |
| 121 } | 121 } |
| 122 dec := gob.NewDecoder(bytes.NewReader(ent.GobEncodedMap)) | 122 dec := gob.NewDecoder(bytes.NewReader(ent.GobEncodedMap)) |
| 123 out := map[int64]string{} | 123 out := map[int64]string{} |
| 124 if err := dec.Decode(&out); err != nil { | 124 if err := dec.Decode(&out); err != nil { |
| 125 return nil, err | 125 return nil, err |
| 126 } | 126 } |
| 127 return out, nil | 127 return out, nil |
| 128 } | 128 } |
| 129 | 129 |
| 130 // GetCAByUniqueID returns CN name that corresponds to given unique ID. | 130 // GetCAByUniqueID returns CN name that corresponds to given unique ID. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 } | 165 } |
| 166 | 166 |
| 167 func (m *idToCNmapper) getCAByUniqueID(c context.Context, id int64) (string, err
or) { | 167 func (m *idToCNmapper) getCAByUniqueID(c context.Context, id int64) (string, err
or) { |
| 168 val, err := m.mapping.Get(c) | 168 val, err := m.mapping.Get(c) |
| 169 if err != nil { | 169 if err != nil { |
| 170 return "", err | 170 return "", err |
| 171 } | 171 } |
| 172 mapping := val.Value.(map[int64]string) | 172 mapping := val.Value.(map[int64]string) |
| 173 return mapping[id], nil | 173 return mapping[id], nil |
| 174 } | 174 } |
| OLD | NEW |