blob: d823bb155fdb86b9342a6cc325671b6afc6fa06b [file] [log] [blame]
#!/usr/bin/env python
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
"""
"""
Generates the same test vector for today. The output file is
testVectors.json. This uses a fixed seed and MPIN ID
usage: genVectorFixed.py
"""
import sys
import json
import os
import datetime
import json
import random
from mpin import *
# Initialize M-Pin Domain parameters
mpdom = ffi.new("mpin_domain*")
rtn = libmpin.MPIN_DOMAIN_INIT_NEW(mpdom)
if rtn != 0:
print "initialization failed: Error %s" % rtn
# Seed
seed_hex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263"
seed = seed_hex.decode("hex")
# Assign a seed value
RAW = ffi.new("octet*")
RAWval = ffi.new("char [%s]" % len(seed), seed)
RAW[0].val = RAWval
RAW[0].len = len(seed)
RAW[0].max = len(seed)
# random number generator
RNG = ffi.new("csprng*")
libmpin.CREATE_CSPRNG(RNG,RAW)
# Master Secret Shares
MS1 = ffi.new("octet*")
MS1val = ffi.new("char []", PGS)
MS1[0].val = MS1val
MS1[0].max = PGS
MS1[0].len = PGS
# Generate master secret shares
rtn = libmpin.MPIN_RANDOM_GENERATE(mpdom,RNG,MS1)
if rtn != 0:
print "libmpin.MPIN_RANDOM_GENERATE(mpdom,RNG,MS1) Error %s", rtn
# Hash value of MPIN_ID
HASH_MPIN_ID = ffi.new("octet*")
HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES)
HASH_MPIN_ID[0].val = HASH_MPIN_IDval
HASH_MPIN_ID[0].max = HASH_BYTES
HASH_MPIN_ID[0].len = HASH_BYTES
SERVER_SECRET = ffi.new("octet*")
SERVER_SECRETval = ffi.new("char []", G2)
SERVER_SECRET[0].val = SERVER_SECRETval
SERVER_SECRET[0].max = G2
SERVER_SECRET[0].len = G2
TIME_PERMIT = ffi.new("octet*")
TIME_PERMITval = ffi.new("char []", G1)
TIME_PERMIT[0].val = TIME_PERMITval
TIME_PERMIT[0].max = G1
TIME_PERMIT[0].len = G1
CLIENT_SECRET = ffi.new("octet*")
CLIENT_SECRETval = ffi.new("char []", G1)
CLIENT_SECRET[0].val = CLIENT_SECRETval
CLIENT_SECRET[0].max = G1
CLIENT_SECRET[0].len = G1
# Token stored on computer
TOKEN = ffi.new("octet*")
TOKEN[0].val = ffi.new("char []", G1)
TOKEN[0].max = G1
TOKEN[0].len = G1
UT = ffi.new("octet*")
UTval = ffi.new("char []", G1)
UT[0].val = UTval
UT[0].max = G1
UT[0].len = G1
U = ffi.new("octet*")
Uval = ffi.new("char []", G1)
U[0].val = Uval
U[0].max = G1
U[0].len = G1
X = ffi.new("octet*")
Xval = ffi.new("char []", PGS)
X[0].val = Xval
X[0].max = PGS
X[0].len = PGS
Y = ffi.new("octet*")
Yval = ffi.new("char []", PGS)
Y[0].val = Yval
Y[0].max = PGS
Y[0].len = PGS
lenEF = 12 * PFS
E = ffi.new("octet*")
Eval = ffi.new("char []", lenEF)
E[0].val = Eval
E[0].max = lenEF
E[0].len = lenEF
F = ffi.new("octet*")
Fval = ffi.new("char []", lenEF)
F[0].val = Fval
F[0].max = lenEF
F[0].len = lenEF
def genVector(mpin_id, date, PIN1, PIN2, test_no):
"""Generate a single test vector
Use mpin_id and date to generate a
valid Client Secret and Time Permit
Args::
mpin_id: The M-Pin ID
date: The date of M-Pin Authentication
PIN1: PIN for generating token
PIN2: PIN for authenticating
test_no: Test vector identifier
Returns:
vector: A test vector
Raises:
Exception
"""
vector = {}
vector['test_no'] = test_no
vector['mpin_id'] = mpin_id
# Generate server secret shares
print "MS1 ", toHex(MS1)
rtn = libmpin.MPIN_GET_SERVER_SECRET(mpdom,MS1,SERVER_SECRET)
if rtn != 0:
print "libmpin.MPIN_GET_SERVER_SECRET(mpdom,MS1,SS1) Error %s" % rtn
vector['SERVER_SECRET'] = toHex(SERVER_SECRET)
print "SERVER_SECRET ", toHex(SERVER_SECRET)
# Identity
MPIN_ID = ffi.new("octet*")
MPIN_IDval = ffi.new("char [%s]" % len(mpin_id), mpin_id)
MPIN_ID[0].val = MPIN_IDval
MPIN_ID[0].max = len(mpin_id)
MPIN_ID[0].len = len(mpin_id)
vector['MPIN_ID_HEX'] = toHex(MPIN_ID)
print "mpin_id ", mpin_id
print "MPIN_ID_HEX ", toHex(MPIN_ID)
# Hash MPIN_ID
libmpin.hash(ffi.NULL, -1, MPIN_ID, ffi.NULL, HASH_MPIN_ID);
vector['HASH_MPIN_ID_HEX'] = toHex(HASH_MPIN_ID)
print "HASH_MPIN_ID_HEX ", toHex(HASH_MPIN_ID)
# Generate client secret shares
rtn = libmpin.MPIN_GET_CLIENT_MULTIPLE(mpdom,MS1,HASH_MPIN_ID,TOKEN)
assert rtn is 0, "CS1"
vector['CLIENT_SECRET'] = toHex(TOKEN)
print "HASH_MPIN_ID ", toHex(HASH_MPIN_ID)
print "CLIENT_SECRET ", toHex(TOKEN)
# Generate Time Permit shares
rtn = libmpin.MPIN_GET_CLIENT_PERMIT(mpdom,date,MS1,HASH_MPIN_ID,TIME_PERMIT)
assert rtn is 0, "TP1"
vector['TIME_PERMIT'] = toHex(TIME_PERMIT)
vector['DATE'] = date
print "TIME_PERMIT", TIME_PERMIT
print "DATE", date
# Client extracts PIN from secret to create Token
rtn = libmpin.MPIN_EXTRACT_PIN(mpdom, MPIN_ID, PIN1, TOKEN)
assert rtn is 0, "TOKEN"
vector['PIN1'] = PIN1
vector['TOKEN'] = toHex(TOKEN)
print "TOKEN ", toHex(TOKEN)
# Client first pass
rtn = libmpin.MPIN_CLIENT_1(mpdom,date,MPIN_ID,RNG,X,PIN2,TOKEN, CLIENT_SECRET,U,TIME_PERMIT,UT,ffi.NULL,ffi.NULL);
assert rtn is 0, "MPIN_CLIENT_1"
vector['PIN2'] = PIN2
vector['X'] = toHex(X)
vector['U'] = toHex(U)
vector['UT'] = toHex(UT)
vector['SEC'] = toHex(CLIENT_SECRET)
print 'PIN2 ', PIN2
print 'X ', toHex(X)
print 'U ', toHex(U)
print 'UT ', toHex(UT)
print 'SEC', toHex(CLIENT_SECRET)
# Server generates Random number Y and sends it to Client
rtn = libmpin.MPIN_RANDOM_GENERATE(mpdom,RNG,Y)
assert rtn is 0, "MPIN_RANDOM_GENERATE"
vector['Y'] = toHex(Y)
print 'Y', toHex(Y)
# Client second pass
rtn = libmpin.MPIN_CLIENT_2(mpdom,X,Y,CLIENT_SECRET)
assert rtn is 0, "MPIN_CLIENT_2"
vector['V'] = toHex(CLIENT_SECRET)
print 'V ', toHex(CLIENT_SECRET)
# Server second pass
rtn = libmpin.MPIN_MINI_SERVER(mpdom, date, MPIN_ID, Y, SERVER_SECRET, U,UT,CLIENT_SECRET,E,F)
if PIN1 == PIN2:
assert rtn == 0, "successful authentication"
else:
assert rtn == -19, "failed authentication"
return vector
if __name__ == '__main__':
# List of test vectors
vectors = []
# Today's date in epoch days
date = libmpin.today()
mpin_id = "testUser@miracl.com"
PIN1 = 1234
PIN2 = PIN1
vector = genVector(mpin_id, date, PIN1, PIN2, 0)
vectors.append(vector)
# Write to JSON file
json.dump(vectors, open("testVectors.json", "w"))