Skip to content

Commit

Permalink
start migrating to the new crypto scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Feb 18, 2022
1 parent 0925bd2 commit 67ec801
Show file tree
Hide file tree
Showing 11 changed files with 1,388 additions and 4,041 deletions.
116 changes: 92 additions & 24 deletions biscuit.go
Expand Up @@ -3,14 +3,15 @@ package biscuit
import (
"bytes"
"crypto/rand"
"crypto/sha256"
//"crypto/sha256"
"crypto/ed25519"
"errors"
"fmt"
"io"

"github.com/biscuit-auth/biscuit-go/datalog"
"github.com/biscuit-auth/biscuit-go/pb"
"github.com/biscuit-auth/biscuit-go/sig"
//"github.com/biscuit-auth/biscuit-go/sig"
"google.golang.org/protobuf/proto"
)

Expand Down Expand Up @@ -39,9 +40,11 @@ var (
ErrEmptyKeys = errors.New("biscuit: empty keys")
// ErrUnknownPublicKey is returned when verifying a biscuit with the wrong public key
ErrUnknownPublicKey = errors.New("biscuit: unknown public key")

ErrInvalidSignature = errors.New("biscuit: invalid signature")
)

func New(rng io.Reader, root sig.Keypair, baseSymbols *datalog.SymbolTable, authority *Block) (*Biscuit, error) {
func New(rng io.Reader, root ed25519.PrivateKey, baseSymbols *datalog.SymbolTable, authority *Block) (*Biscuit, error) {
if rng == nil {
rng = rand.Reader
}
Expand All @@ -58,6 +61,8 @@ func New(rng io.Reader, root sig.Keypair, baseSymbols *datalog.SymbolTable, auth

symbols.Extend(authority.symbols)

nextPrivateKey, nextPublicKey, err := ed25519.GenerateKey(rng)

protoAuthority, err := tokenBlockToProtoBlock(authority)
if err != nil {
return nil, err
Expand All @@ -67,13 +72,24 @@ func New(rng io.Reader, root sig.Keypair, baseSymbols *datalog.SymbolTable, auth
return nil, err
}

ts := &sig.TokenSignature{}
ts.Sign(rng, root, marshalledAuthority)
toSign := append(marshalledAuthority[:], nextPublicKey[:]...)
signature := ed25519.Sign(root, toSign)

signedBlock := &pb.SignedBlock{
Block: marshalledAuthority,
NextKey: nextPublicKey,
Signature: signature,
}

proof := &pb.Proof{
Content: &pb.Proof_NextSecret{
NextSecret: nextPrivateKey,
},
}

container := &pb.Biscuit{
Authority: marshalledAuthority,
Keys: [][]byte{root.Public().Bytes()},
Signature: tokenSignatureToProtoSignature(ts),
Authority: signedBlock,
Proof: proof,
}

return &Biscuit{
Expand All @@ -87,11 +103,16 @@ func (b *Biscuit) CreateBlock() BlockBuilder {
return NewBlockBuilder(uint32(len(b.blocks)+1), b.symbols.Clone())
}

func (b *Biscuit) Append(rng io.Reader, keypair sig.Keypair, block *Block) (*Biscuit, error) {
func (b *Biscuit) Append(rng io.Reader, keypair ed25519.PrivateKey, block *Block) (*Biscuit, error) {
if b.container == nil {
return nil, errors.New("biscuit: append failed, token is sealed")
}

privateKey := b.container.Proof.GetNextSecret()
if privateKey == nil {
return nil, errors.New("biscuit: append failed, token is sealed")
}

if !b.symbols.IsDisjoint(block.symbols) {
return nil, ErrSymbolTableOverlap
}
Expand All @@ -114,6 +135,8 @@ func (b *Biscuit) Append(rng io.Reader, keypair sig.Keypair, block *Block) (*Bis
symbols := b.symbols.Clone()
symbols.Extend(block.symbols)

nextPrivateKey, nextPublicKey, err := ed25519.GenerateKey(rng)

// serialize and sign the new block
protoBlock, err := tokenBlockToProtoBlock(block)
if err != nil {
Expand All @@ -124,22 +147,29 @@ func (b *Biscuit) Append(rng io.Reader, keypair sig.Keypair, block *Block) (*Bis
return nil, err
}

ts, err := protoSignatureToTokenSignature(b.container.Signature)
if err != nil {
return nil, err
toSign := append(marshalledBlock[:], nextPublicKey[:]...)
signature := ed25519.Sign(privateKey, toSign)

signedBlock := &pb.SignedBlock{
Block: marshalledBlock,
NextKey: nextPublicKey,
Signature: signature,
}

proof := &pb.Proof{
Content: &pb.Proof_NextSecret{
NextSecret: nextPrivateKey,
},
}
ts.Sign(rng, keypair, marshalledBlock)

// clone container and append new marshalled block and public key
container := &pb.Biscuit{
Authority: append([]byte{}, b.container.Authority...),
Blocks: append([][]byte{}, b.container.Blocks...),
Keys: append([][]byte{}, b.container.Keys...),
Signature: tokenSignatureToProtoSignature(ts),
Authority: b.container.Authority,
Blocks: append([]*pb.SignedBlock{}, b.container.Blocks...),
Proof: proof,
}

container.Blocks = append(container.Blocks, marshalledBlock)
container.Keys = append(container.Keys, keypair.Public().Bytes())
container.Blocks = append(container.Blocks, signedBlock)

return &Biscuit{
authority: authority,
Expand All @@ -149,11 +179,47 @@ func (b *Biscuit) Append(rng io.Reader, keypair sig.Keypair, block *Block) (*Bis
}, nil
}

func (b *Biscuit) Verify(root sig.PublicKey) (Verifier, error) {
if err := b.checkRootKey(root); err != nil {
func (b *Biscuit) Verify(root ed25519.PublicKey) (Verifier, error) {
/*if err := b.checkRootKey(root); err != nil {
return nil, err
}*/

currentKey := root

toVerify := append(b.container.Authority.Block[:], b.container.Authority.NextKey[:]...)

if ok := ed25519.Verify(currentKey, toVerify, b.container.Authority.Signature); !ok {
return nil, ErrInvalidSignature
}

for _, block := range b.container.Blocks {
toVerify := append(block.Block[:], block.NextKey[:]...)

if ok := ed25519.Verify(currentKey, toVerify, block.Signature); !ok {
return nil, ErrInvalidSignature
}

currentKey = block.NextKey
}

privateKey := b.container.Proof.GetNextSecret()
if privateKey == nil {
return nil, errors.New("biscuit: sealed token verification not implemented")
}

publicKey := ed25519.NewKeyFromSeed(privateKey).Public()
if bytes.Compare(currentKey, publicKey.([]byte)) != 0 {
return nil, errors.New("biscuit: invalid signature")
}
//if b.p
/*FIXME: sealed token
if b.blocks.Len() == 0 {
toVerify := append(b.Authority.Block[:], b.Authority.nextKey[:], b. Authority.Signature[:]...)
} else {
block := b.blocks[b.blocks.Len() - 1]
toVerify := append(block.Block[:], block.nextKey[:], block.Signature[:]...)
}*/

return NewVerifier(b)
}

Expand Down Expand Up @@ -197,6 +263,7 @@ func (b *Biscuit) GetBlockID(fact Fact) (int, error) {
return 0, ErrFactNotFound
}

/*
// SHA256Sum returns a hash of `count` biscuit blocks + the authority block
// along with their respective keys.
func (b *Biscuit) SHA256Sum(count int) ([]byte, error) {
Expand Down Expand Up @@ -228,7 +295,7 @@ func (b *Biscuit) SHA256Sum(count int) ([]byte, error) {
}
return h.Sum(nil), nil
}
}*/

func (b *Biscuit) BlockCount() int {
return len(b.container.Blocks)
Expand All @@ -252,7 +319,8 @@ Biscuit {
)
}

func (b *Biscuit) checkRootKey(root sig.PublicKey) error {
/*
func (b *Biscuit) checkRootKey(root ed25519.PublicKey) error {
if len(b.container.Keys) == 0 {
return ErrEmptyKeys
}
Expand All @@ -261,7 +329,7 @@ func (b *Biscuit) checkRootKey(root sig.PublicKey) error {
}
return nil
}
}*/

func (b *Biscuit) generateWorld(symbols *datalog.SymbolTable) (*datalog.World, error) {
world := datalog.NewWorld()
Expand Down
19 changes: 10 additions & 9 deletions builder.go
@@ -1,13 +1,14 @@
package biscuit

import (
"crypto/ed25519"
"crypto/rand"
"errors"
"io"

"github.com/biscuit-auth/biscuit-go/datalog"
"github.com/biscuit-auth/biscuit-go/pb"
"github.com/biscuit-auth/biscuit-go/sig"
//"github.com/biscuit-auth/biscuit-go/sig"
"google.golang.org/protobuf/proto"
)

Expand All @@ -25,7 +26,7 @@ type Builder interface {

type builder struct {
rng io.Reader
root sig.Keypair
root ed25519.PrivateKey

symbolsStart int
symbols *datalog.SymbolTable
Expand All @@ -50,7 +51,7 @@ func WithSymbols(symbols *datalog.SymbolTable) builderOption {
}
}

func NewBuilder(root sig.Keypair, opts ...builderOption) Builder {
func NewBuilder(root ed25519.PrivateKey, opts ...builderOption) Builder {
b := &builder{
rng: rand.Reader,
root: root,
Expand Down Expand Up @@ -135,11 +136,11 @@ func (u *Unmarshaler) Unmarshal(serialized []byte) (*Biscuit, error) {
}

pbAuthority := new(pb.Block)
if err := proto.Unmarshal(container.Authority, pbAuthority); err != nil {
if err := proto.Unmarshal(container.Authority.Block, pbAuthority); err != nil {
return nil, err
}

signature, err := protoSignatureToTokenSignature(container.Signature)
/*signature, err := protoSignatureToTokenSignature(container.Signature)
if err != nil {
return nil, err
}
Expand All @@ -158,7 +159,7 @@ func (u *Unmarshaler) Unmarshal(serialized []byte) (*Biscuit, error) {
signedBlocks = append(signedBlocks, container.Blocks...)
if err := signature.Verify(pubKeys, signedBlocks); err != nil {
return nil, err
}
}*/

authority, err := protoBlockToTokenBlock(pbAuthority)
if err != nil {
Expand All @@ -172,13 +173,13 @@ func (u *Unmarshaler) Unmarshal(serialized []byte) (*Biscuit, error) {
blocks := make([]*Block, len(container.Blocks))
for i, sb := range container.Blocks {
pbBlock := new(pb.Block)
if err := proto.Unmarshal(sb, pbBlock); err != nil {
if err := proto.Unmarshal(sb.Block, pbBlock); err != nil {
return nil, err
}

if int(pbBlock.Index) != i+1 {
/*if int(pbBlock.Index) != i+1 {
return nil, ErrInvalidBlockIndex
}
}*/

block, err := protoBlockToTokenBlock(pbBlock)
if err != nil {
Expand Down

0 comments on commit 67ec801

Please sign in to comment.