client: upload public key if necessary whenever uploading a signed blob

Change-Id: I2e61da4fa2eeae2332c67902f8dd5f064b027835
This commit is contained in:
Brad Fitzpatrick 2013-09-22 19:38:42 +01:00
parent 1834d682b8
commit 63b4f390cb
3 changed files with 32 additions and 8 deletions

9
TODO
View File

@ -4,6 +4,15 @@ There are two TODO lists. This file (good for airplanes) and the online bug trac
Offline list:
-- camput's havecache initialization should move up a layer to
to be global to all commands, not specific to "camput file".
(the statcache can stay in file). otherwise, we have no haveCache
on the pkg/client.*Client and the UploadAndSignBlob call (for
creating permanodes and other claims) can't efficiently upload its
public key if the server doesn't already have it. currently it
has to try to upload it (doing a remote HTTP stat) each time
when using "camput permanode" or "camput attr".
-- use 'int' instead of 'int64' for blob sizes everywhere. blobs
have a max size of 10-32 MB anyway. definitely not bigger than
what will fit in memory (which is what int means)

View File

@ -802,13 +802,13 @@ func (c *Client) initEntityFetcher() {
// sigTime optionally specifies the signature time.
// If zero, the current time is used.
func (c *Client) SignBlob(bb schema.Buildable, sigTime time.Time) (string, error) {
camliSigBlobref := c.SignerPublicKeyBlobref()
if !camliSigBlobref.Valid() {
sigRef := c.SignerPublicKeyBlobref()
if !sigRef.Valid() {
// TODO: more helpful error message
return "", errors.New("No public key configured.")
}
b := bb.Builder().SetSigner(camliSigBlobref).Blob()
b := bb.Builder().SetSigner(sigRef).Blob()
return c.Sign(&jsonsign.SignRequest{
UnsignedJSON: b.JSON(),
SignatureTime: sigTime,
@ -820,6 +820,20 @@ func (c *Client) UploadAndSignBlob(b schema.AnyBlob) (*PutResult, error) {
if err != nil {
return nil, err
}
// sigRef is guaranteed valid at this point, because SignBlob
// succeeded. If we don't know for sure that the server
// already has this public key, upload it. And do it serially
// so by the time we do the second upload of the signed blob,
// any synchronous indexing on the server won't fail due to a
// missing public key.
sigRef := c.SignerPublicKeyBlobref()
if _, keyUploaded := c.haveCache.StatBlobCache(sigRef); !keyUploaded {
if _, err := c.uploadString(publicKeyArmored); err != nil {
return nil, err
}
}
return c.uploadString(signed)
}

View File

@ -192,7 +192,8 @@ func fileExists(name string) bool {
var (
signerPublicKeyRefOnce sync.Once
signerPublicKeyRef blob.Ref
signerPublicKeyRef blob.Ref // of publicKeyArmored
publicKeyArmored string
)
// TODO: move to config package?
@ -202,10 +203,10 @@ func SignerPublicKeyBlobref() blob.Ref {
}
func initSignerPublicKeyBlobref() {
signerPublicKeyRef, _ = getSignerPublicKeyBlobref()
signerPublicKeyRef, publicKeyArmored, _ = getSignerPublicKeyBlobref()
}
func getSignerPublicKeyBlobref() (signerRef blob.Ref, ok bool) {
func getSignerPublicKeyBlobref() (signerRef blob.Ref, armored string, ok bool) {
configOnce.Do(parseConfig)
key := "keyId"
keyId, ok := config[key].(string)
@ -229,7 +230,7 @@ func getSignerPublicKeyBlobref() (signerRef blob.Ref, ok bool) {
log.Printf("Couldn't find keyId %q in secret ring: %v", keyId, err)
return
}
armored, err := jsonsign.ArmoredPublicKey(entity)
armored, err = jsonsign.ArmoredPublicKey(entity)
if err != nil {
log.Printf("Error serializing public key: %v", err)
return
@ -259,7 +260,7 @@ func getSignerPublicKeyBlobref() (signerRef blob.Ref, ok bool) {
}
}
return br, true
return br, armored, true
}
func (c *Client) GetBlobFetcher() blob.SeekFetcher {