Commit 2b41c757 authored by Sietse Ringers's avatar Sietse Ringers

Switch to bigint that JSON-encodes to base64

parent 979c8287
......@@ -5,11 +5,11 @@ import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"math/big"
"time"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
)
const (
......
......@@ -2,9 +2,10 @@ package irma
import (
"fmt"
"math/big"
"strings"
"time"
"github.com/mhe/gabi/big"
)
// CredentialInfo contains all information of an IRMA credential.
......
......@@ -2,10 +2,10 @@ package sessiontest
import (
"encoding/json"
"math/big"
"testing"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/test"
"github.com/privacybydesign/irmago/irmaclient"
......
......@@ -4,10 +4,11 @@ import (
"crypto/sha256"
"encoding/asn1"
"log"
"math/big"
gobig "math/big"
"github.com/bwesterb/go-atum"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
)
// SignedMessage is a message signed with an attribute-based signature
......@@ -35,7 +36,7 @@ func (sm *SignedMessage) MatchesNonceAndContext(request *SignatureRequest) bool
// where serverNonce is the nonce sent by the signature requestor.
func ASN1ConvertSignatureNonce(message string, nonce *big.Int, timestamp *atum.Timestamp) *big.Int {
msgHash := sha256.Sum256([]byte(message))
tohash := []interface{}{nonce, new(big.Int).SetBytes(msgHash[:])}
tohash := []interface{}{nonce.Value(), new(gobig.Int).SetBytes(msgHash[:])}
if timestamp != nil {
tohash = append(tohash, timestamp.Sig.Data)
}
......
......@@ -2,7 +2,6 @@ package irmaclient
import (
"crypto/rand"
"math/big"
"sort"
"strconv"
"time"
......@@ -11,6 +10,7 @@ import (
raven "github.com/getsentry/raven-go"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/fs"
)
......
......@@ -3,11 +3,12 @@ package irmaclient
import (
"encoding/json"
"errors"
"math/big"
gobig "math/big"
"os"
"testing"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/internal/fs"
"github.com/privacybydesign/irmago/internal/test"
......@@ -86,8 +87,8 @@ func verifyPaillierKey(t *testing.T, PrivateKey *paillierPrivateKey) {
require.NotNil(t, PrivateKey.U)
require.NotNil(t, PrivateKey.PublicKey.N)
require.Equal(t, big.NewInt(1), new(big.Int).Exp(big.NewInt(2), PrivateKey.L, PrivateKey.N))
require.Equal(t, PrivateKey.NSquared, new(big.Int).Exp(PrivateKey.N, big.NewInt(2), nil))
require.Equal(t, gobig.NewInt(1), new(gobig.Int).Exp(gobig.NewInt(2), PrivateKey.L, PrivateKey.N))
require.Equal(t, PrivateKey.NSquared, new(gobig.Int).Exp(PrivateKey.N, gobig.NewInt(2), nil))
plaintext := "Hello Paillier!"
ciphertext, err := PrivateKey.Encrypt([]byte(plaintext))
......@@ -266,7 +267,8 @@ func TestPaillier(t *testing.T) {
commcipher := new(big.Int).SetBytes(bytes)
// [[ c ]]^resp * [[ comm ]]
cipher.Exp(cipher, resp, sk.NSquared).Mul(cipher, commcipher).Mod(cipher, sk.NSquared)
nsquared := big.Convert(sk.NSquared)
cipher.Exp(cipher, resp, nsquared).Mul(cipher, commcipher).Mod(cipher, nsquared)
bytes, err = sk.Decrypt(cipher.Bytes())
require.NoError(t, err)
......
......@@ -5,7 +5,6 @@ import (
"crypto/sha256"
"encoding/base64"
"fmt"
"math/big"
"net/http"
"strconv"
"strings"
......@@ -13,6 +12,7 @@ import (
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago"
)
......
......@@ -2,6 +2,7 @@ package irmaclient
import (
"encoding/json"
"math/big"
"github.com/credentials/go-go-gadget-paillier"
......@@ -12,35 +13,11 @@ type paillierPrivateKey paillier.PrivateKey
type paillierPublicKey paillier.PublicKey
func (psk *paillierPrivateKey) UnmarshalJSON(bytes []byte) (err error) {
// First try to unmarshal it as a keypair serialized in the old Android format
oldFormat := &struct {
PrivateKey struct {
L *big.Int `json:"lambda"`
U *big.Int `json:"preCalculatedDenominator"`
} `json:"privateKey"`
PublicKey struct {
N *big.Int `json:"n"`
G *big.Int `json:"g"`
NSquared *big.Int `json:"nSquared"`
} `json:"publicKey"`
}{}
if err = json.Unmarshal(bytes, oldFormat); err != nil {
return
}
if oldFormat.PrivateKey.L != nil {
psk.L = oldFormat.PrivateKey.L
psk.U = oldFormat.PrivateKey.U
psk.PublicKey.G = oldFormat.PublicKey.G
psk.PublicKey.N = oldFormat.PublicKey.N
psk.PublicKey.NSquared = oldFormat.PublicKey.NSquared
return nil
}
newFormat := new(paillier.PrivateKey)
if err = json.Unmarshal(bytes, newFormat); err != nil {
sk := new(paillier.PrivateKey)
if err = json.Unmarshal(bytes, sk); err != nil {
return
}
*psk = paillierPrivateKey(*newFormat)
*psk = paillierPrivateKey(*sk)
return
}
......
......@@ -6,10 +6,9 @@ import (
"net/url"
"strings"
"math/big"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago"
)
......
......@@ -28,10 +28,11 @@ import (
"crypto/x509"
"encoding/asn1"
"encoding/pem"
"math/big"
gobig "math/big"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago/internal/fs"
)
......@@ -923,7 +924,7 @@ func (conf *Configuration) VerifySignature(id SchemeManagerIdentifier) (err erro
if err != nil {
return err
}
ints := make([]*big.Int, 0, 2)
ints := make([]*gobig.Int, 0, 2)
_, err = asn1.Unmarshal(sig, &ints)
// Verify signature
......
......@@ -2,12 +2,13 @@ package irma
import (
"encoding/json"
"math/big"
"os"
"path/filepath"
"testing"
"time"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago/internal/fs"
"github.com/privacybydesign/irmago/internal/test"
"github.com/stretchr/testify/require"
......@@ -298,24 +299,6 @@ func TestVerifyValidSig(t *testing.T) {
require.Equal(t, attrs[0].Status, AttributeProofStatusPresent)
require.Equal(t, attrs[0].Value["en"], "456")
// Test if we can verify it with a request that contains strings instead of ints for nonce and context
stringRequest := "{\"nonce\": \"42\", \"context\": \"1337\", \"message\":\"I owe you everything\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
stringSigRequestJSON := []byte(stringRequest)
stringSigRequest := &SignatureRequest{}
json.Unmarshal(stringSigRequestJSON, stringSigRequest)
// Test marshalling of 'string' fields:
require.Equal(t, stringSigRequest.Nonce, big.NewInt(42))
require.Equal(t, stringSigRequest.Context, big.NewInt(1337))
// Test if we can verify it with the original request
attrs, status, err = irmaSignedMessage.Verify(conf, sigRequest)
require.NoError(t, err)
require.Equal(t, status, ProofStatusValid)
require.Len(t, attrs, 1)
require.Equal(t, attrs[0].Status, AttributeProofStatusPresent)
require.Equal(t, attrs[0].Value["en"], "456")
// Test verify against unmatched request (i.e. different nonce, context or message)
unmatched := "{\"nonce\": 42, \"context\": 1337, \"message\":\"I owe you NOTHING\",\"content\":[{\"label\":\"Student number (RU)\",\"attributes\":[\"irma-demo.RU.studentCard.studentID\"]}]}"
unmatchedSigRequestJSON := []byte(unmatched)
......
......@@ -4,13 +4,14 @@ package main
import (
"encoding/base64"
"fmt"
"math/big"
"os"
"time"
"encoding/json"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago"
)
......
......@@ -3,16 +3,13 @@ package irma
import (
"fmt"
"io/ioutil"
"math/big"
"strconv"
"strings"
"time"
"encoding/json"
"github.com/bwesterb/go-atum"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
"github.com/privacybydesign/irmago/internal/fs"
)
......@@ -359,46 +356,6 @@ func (sr *SignatureRequest) GetNonce() *big.Int {
return ASN1ConvertSignatureNonce(sr.Message, sr.Nonce, sr.Timestamp)
}
// Convert fields in JSON string to BigInterger if they are string
// Supply fieldnames as a slice as second argument
func convertFieldsToBigInt(jsonString []byte, fieldNames []string) ([]byte, error) {
var rawRequest map[string]json.RawMessage
err := json.Unmarshal(jsonString, &rawRequest)
if err != nil {
return nil, err
}
for _, fieldName := range fieldNames {
fieldString := string(rawRequest[fieldName])
rawRequest[fieldName] = []byte(strings.Trim(fieldString, "\""))
}
return json.Marshal(rawRequest)
}
// Custom Unmarshalling to support both json with string and int fields for nonce and context
// i.e. {"nonce": "42", "context": "1337", ... } and {"nonce": 42, "context": 1337, ... }
func (sr *SignatureRequest) UnmarshalJSON(b []byte) error {
type signatureRequestTemp SignatureRequest // To avoid 'recursive unmarshalling'
fixedRequest, err := convertFieldsToBigInt(b, []string{"nonce", "context"})
if err != nil {
return err
}
var result signatureRequestTemp
err = json.Unmarshal(fixedRequest, &result)
if err != nil {
return err
}
sr.DisclosureRequest = result.DisclosureRequest
sr.Message = result.Message
return err
}
func (sr *SignatureRequest) SignatureFromMessage(message interface{}) (*SignedMessage, error) {
signature, ok := message.(gabi.ProofList)
......
......@@ -4,10 +4,11 @@ import (
"crypto/sha256"
"encoding/asn1"
"errors"
"math/big"
gobig "math/big"
"github.com/bwesterb/go-atum"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
)
// GetTimestamp GETs a signed timestamp (a signature over the current time and the parameters)
......@@ -31,12 +32,24 @@ func GetTimestamp(message string, sigs []*big.Int, disclosed [][]*big.Int) (*atu
func TimestampRequest(message string, sigs []*big.Int, disclosed [][]*big.Int) ([]byte, error) {
msgHash := sha256.Sum256([]byte(message))
// Convert the sigs and disclosed (double) slices to (double) slices of gobig.Int's for asn1
sigsint := make([]*gobig.Int, len(sigs))
disclosedint := make([][]*gobig.Int, len(disclosed))
for i, k := range sigs {
sigsint[i] = k.Value()
}
for i, _ := range disclosed {
disclosedint[i] = make([]*gobig.Int, len(disclosed[i]))
for j, k := range disclosed[i] {
disclosedint[i][j] = k.Value()
}
}
bts, err := asn1.Marshal(struct {
Sigs []*big.Int
Sigs []*gobig.Int
MsgHash []byte
Disclosed [][]*big.Int
Disclosed [][]*gobig.Int
}{
sigs, msgHash[:], disclosed,
sigsint, msgHash[:], disclosedint,
})
if err != nil {
return nil, err
......
package irma
import (
"math/big"
"time"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/mhe/gabi/big"
)
// ProofStatus is the status of the complete proof
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment