Пример #1
0
// WalletToken gets a token from wallet that matches usage.
// The token is reissued for owner if not nil.
// If the token is a subscription-token and owner is not present, it
// is stored and a "NeedReissue" error is returned.
func (c *Client) WalletToken(usage string, owner *[ed25519.PublicKeySize]byte) (tokenHash []byte, err error) {
	newToken, params, pubkeyUsed, err := c.getTokenFromWallet(usage)
	if err != nil {
		return nil, err
	}
	// Cache token, params
	tokenUnmarshalled, err := token.Unmarshal(newToken)
	if err != nil {
		c.LastError = err
		return nil, ErrFatal
	}
	// Parse pubkeyUsed and add to keypool
	signerPubKey, err := new(signkeys.PublicKey).Unmarshal(pubkeyUsed)
	if err != nil {
		c.LastError = err
		return nil, ErrFatal
	}
	keyid, err := c.packetClient.Keypool.LoadKey(signerPubKey)
	if err != nil && err != keypool.ErrExists {
		c.LastError = err
		return nil, ErrFatal
	}
	c.packetClient.Keypool.SaveKey(*keyid)
	// If we have params this is not renewable
	renewable := false
	if params == nil || len(params) == 0 {
		renewable = true
	} else {
		// Unless the params state otherwise....
		_, _, _, canReissue, err := types.UnmarshalParams(params)
		if err != nil {
			c.LastError = err
			return nil, ErrFatal
		}
		if canReissue {
			renewable = true
		}
	}
	//tokenUnmarshalled.KeyID
	ownerPubkey, ownerPrivkey := splitKey(c.walletKey)
	// Set tokenentry struct for storage
	tokenentry := TokenEntry{
		Hash:         tokenUnmarshalled.Hash(),
		Token:        newToken,
		Params:       params,
		OwnerPubKey:  ownerPubkey,
		OwnerPrivKey: ownerPrivkey,
		Renewable:    renewable,
		CanReissue:   true,
		Usage:        signerPubKey.Usage,
		Expire:       signerPubKey.Expire,
	}
	err = c.walletStore.SetToken(tokenentry) // Cache current state
	if err != nil {
		c.LastError = err
		return nil, ErrFatal
	}
	if owner == nil && renewable == false {
		return tokenentry.Hash, ErrNeedReissue
	}
	// Reissue
	return c.ReissueToken(tokenentry.Hash, owner)
}
Пример #2
0
// Reissue creates a request to be sent to the server to reissue a new token for an old token. oldOwner is the Private key for whoever owned oldToken.
// NewOwner is the public key for whoever is to own the new token. Both can be nil.
func (c Client) Reissue(oldTokenEnc []byte, oldOwner *[ed25519.PrivateKeySize]byte, newOwner *[ed25519.PublicKeySize]byte, params []byte) (toServer []byte, storeLocal *types.ReissuePacketPrivate, err error) {
	packet := new(types.ReissuePacket)
	packet.CallType = types.CallTypeReissue
	oldToken, err := token.Unmarshal(oldTokenEnc)
	if err != nil {
		return nil, nil, err
	}
	// Get info from parameters
	pubKey, pubParams, _, canReissue, err := types.UnmarshalParams(params)
	if err != nil {
		return nil, nil, err
	}
	// Verify that oldToken and params match
	oldKeyID := new([signkeys.KeyIDSize]byte)
	copy(oldKeyID[:], oldToken.KeyID)
	oldPubKey, err := c.Keypool.Lookup(*oldKeyID)
	if err != nil {
		return nil, nil, err
	}
	// Verify usage
	if oldPubKey.Usage != pubKey.Usage {
		return nil, nil, ErrParamMismatch
	}
	// Verify same service-guard
	if oldPubKey.Signer != pubKey.Signer {
		return nil, nil, ErrParamMismatch
	}
	// Add parameter publickey to keypool
	saveID, err := c.Keypool.LoadKey(pubKey)
	if err != nil && err != keypool.ErrExists {
		return nil, nil, err
	}
	// Save key to permanent storage
	if err == nil {
		c.Keypool.SaveKey(*saveID)
	}
	// Create new token data
	blindMessage, blindFactors, newToken, err := c.NewToken(pubKey, pubParams, newOwner)
	if err != nil {
		return nil, nil, err
	}
	packet.Token, err = oldToken.Marshal()
	if err != nil {
		return nil, nil, err
	}
	packet.BlindToken, err = blindMessage.Marshal()
	if err != nil {
		return nil, nil, err
	}
	packet.Params = params
	_, owner := oldToken.Properties()
	if owner != nil {
		if oldOwner == nil {
			return nil, nil, ErrMissingSigner
		}
	}
	packet.Sign(oldOwner)
	rpacket, err := packet.Marshal()
	if err != nil {
		return nil, nil, err
	}
	local := new(types.ReissuePacketPrivate)
	local.CanReissue = canReissue
	local.PublicKey, err = pubKey.Marshal()
	if err != nil {
		return nil, nil, err
	}
	local.Factors, err = blindFactors.Marshal()
	if err != nil {
		return nil, nil, err
	}
	local.Token, err = newToken.Marshal()
	if err != nil {
		return nil, nil, err
	}
	rhash := packet.Hash()
	local.RequestHash = rhash[:]
	local.Request = rpacket

	return rpacket, local, nil
}