Commit c9d0b00a authored by Josh Ji's avatar Josh Ji

setPin, getPinToken, usePinToken and some dummy or unnecessary stuff while testing and debugging

parent fc423e41
This diff is collapsed.
......@@ -26,6 +26,7 @@ public class AuthenticatorGetAssertion {
byte[] clientDataHash;
boolean[] options;
PublicKeyCredentialDescriptor[] allow;
private byte[] pinUvAuthParam;
public AuthenticatorGetAssertion(CBORDecoder decoder) throws UserException {
......@@ -117,8 +118,10 @@ public class AuthenticatorGetAssertion {
decoder.skipEntry();
break;
case 0x06:
// Pin stuff
decoder.skipEntry();
// Pin UV Auth Param // 0x06
pinUvAuthParam = new byte[16];
if(decoder.readByteString(pinUvAuthParam, (short)0 ) < (short)16)
UserException.throwIt(CTAP2_ERR_PIN_INVALID);
break;
case 0x07:
// Pin protocol
......
......@@ -27,6 +27,7 @@ public class AuthenticatorMakeCredential {
private PublicKeyCredentialUserEntity user;
private PublicKeyCredentialParams params;
private boolean[] options = new boolean[2];
private byte[] pinUvAuthParam;
public PublicKeyCredentialDescriptor[] exclude;
......@@ -282,6 +283,14 @@ public class AuthenticatorMakeCredential {
}
decoder.skipEntry();
break;
case (short)8: // pinUvAuthToken
pinUvAuthParam = new byte[16];
if(decoder.readByteString(pinUvAuthParam, (short)0 ) < (short)16)
UserException.throwIt(CTAP2_ERR_PIN_INVALID);
break;
case (short)9: // pinProtocol
short pinProtocol = decoder.readInt8();
break;
default:
// Skip it transparently
decoder.skipEntry();
......@@ -290,12 +299,16 @@ public class AuthenticatorMakeCredential {
}
}
if(pinUvAuthParam == null){
UserException.throwIt(CTAP2_ERR_PIN_INVALID);
}
// Check we've got stuff like the clientDataHash
if(dataHash == null || rp == null || user == null || params == null) {
UserException.throwIt(CTAP2_ERR_MISSING_PARAMETER);
}
// We're done, I guess
}
......@@ -319,6 +332,14 @@ public class AuthenticatorMakeCredential {
return (exclude != null && exclude.length > 0);
}
/**
*
* @return pinUvAuthToken
*/
public byte[] getPinUvAuthParam(){
return pinUvAuthParam;
}
/**
* Reads the clientDataHash into a buffer.
*
......@@ -326,9 +347,8 @@ public class AuthenticatorMakeCredential {
* @param outOff the offset to begin at.
* @return the length of the data read out.
*/
public short getDataHash(byte[] outBuf, short outOff) {
Util.arrayCopy(dataHash, (short) 0, outBuf, outOff, (short) dataHash.length);
return (short) dataHash.length;
public byte[] getDataHash() {
return dataHash;
}
}
This diff is collapsed.
......@@ -21,7 +21,7 @@ public class ClientPINCommand {
private byte[] y = new byte[32]; // y-coordinate
private byte[] pinUvAuthParam = new byte[64]; // byte string
private byte[] newPinEnc = new byte[64]; // byte string
private byte[] pinHashEnc = new byte[32]; // byte string
private byte[] pinHashEnc = new byte[16]; // byte string, aes256
private byte permissions; // unsigned int
private byte[] rpId = new byte[64]; // text string
byte[] scratch = JCSystem.makeTransientByteArray((short)64, JCSystem.CLEAR_ON_RESET);
......@@ -61,15 +61,15 @@ public class ClientPINCommand {
break;
case PARAMETER_PIN_UV_AUTH_PARAM:
// cborDecoder.readByteString(pinUvAuthParam, (short) 0);
cborDecoder.skipEntry();
cborDecoder.readByteString(pinUvAuthParam, (short) 0);
// cborDecoder.skipEntry();
break;
case PARAMETER_NEW_PIN_ENC:
cborDecoder.readByteString(newPinEnc, (short) 0);
break;
case PARAMETER_PIN_HASH_ENC:
// cborDecoder.readByteString(pinHashEnc, (short) 0);
cborDecoder.skipEntry();
cborDecoder.readByteString(pinHashEnc, (short) 0);
// cborDecoder.skipEntry();
break;
case PARAMETER_PERMISSIONS:
// permissions = cborDecoder.readInt8();
......@@ -93,6 +93,10 @@ public class ClientPINCommand {
return subCommandCode;
}
/**
*
* @return 0x04 || x-coordinate || y-coordinate
*/
public byte[] getKeyAgreement() {
keyAgreement[0] = 0x04;
Util.arrayCopy(x, (short)0, keyAgreement, (short)1, (short)x.length);
......
......@@ -121,14 +121,19 @@ public class IDSecret {
return tempBufferLength;
}
public void writeTempBuffer(byte[] inputBuffer){
if((short)inputBuffer.length > (short)tempBuffer.length){
/**
*
* @param inputBuffer the buffer copy from
* @param offset output offset
*/
public void writeTempBuffer(byte[] inputBuffer, short offset){
if((short)(inputBuffer.length + offset) > (short)tempBuffer.length){
tempBuffer[0] = 'T'; // too
tempBuffer[1] = 'L'; // long
Util.setShort(tempBuffer, (short)2, (short)inputBuffer.length); // input length
return;
}
Util.arrayCopy(inputBuffer, (short)0, tempBuffer, (short)0, (short)inputBuffer.length);
Util.arrayCopy(inputBuffer, (short)0, tempBuffer, offset, (short)inputBuffer.length);
}
/**
......
......@@ -10,5 +10,5 @@ public abstract class PinUvAuthProtocol {
public abstract byte[] getPublicKey();
public abstract byte[] decapsulate(COSEKey peerCoseKey);
public abstract byte[] decrypt(byte[] sharedSecret, byte[] cipherText);
public abstract void verify(byte[] key, byte[] message, byte[] signature);
public abstract boolean verify(byte[] key, byte[] message, byte[] signature);
}
package com.josh.vku2f;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.*;
import javacardx.crypto.Cipher;
import jdk.nashorn.internal.ir.Block;
public class PinUvAuthProtocolOne extends PinUvAuthProtocol{
......@@ -73,8 +75,20 @@ public class PinUvAuthProtocolOne extends PinUvAuthProtocol{
return null;
}
/**
*
* @param key shared key from kdf()
* @param plaintext pinToken
* @return encrypted pinToken
*/
public byte[] encrypt(byte[] key, byte[] plaintext){
return null;
byte[] cipherText = new byte[32];
aesKey.setKey(key, (short)0);
aesEncrypt.init(aesKey, Cipher.MODE_ENCRYPT, IV_ZERO_AES, (short)0, (short)IV_ZERO_AES.length);
aesEncrypt.update(plaintext, (short)0, (short)16, cipherText, (short)0);
aesEncrypt.doFinal(plaintext, (short)16, (short)16, cipherText, (short)16);
return cipherText;
}
@Override
......@@ -87,13 +101,45 @@ public class PinUvAuthProtocolOne extends PinUvAuthProtocol{
return plainText;
}
/**
*
* @param key the key output from kdf()
* @param cipherText encrypted hashedPin
* @return hashed pin
*/
public byte[] decryptHashedPin(byte[] key, byte[] cipherText) {
byte[] hashedPin = new byte[16];
aesKey.setKey(key, (short)0);
aesDecrypt.init(aesKey, Cipher.MODE_DECRYPT, IV_ZERO_AES, (short)0, (short)IV_ZERO_AES.length);
aesDecrypt.doFinal(cipherText, (short)0, (short)16, hashedPin, (short)0);
return hashedPin;
}
/**
*
* @param key pinToken : 32 bytes
* @param message clientDataHash : 32 bytes
* @return signature
*/
public byte[] authenticate(byte[] key, byte[] message){
return null;
return hmac256(key, message);
}
/**
*
* @param key pinToken 32 bytes
* @param message clientDataHash 32 bytes
* @param signature pinUvAuthToken 16 bytes : LEFT(hmac-sha-256(pinToken, clientDataHash), 16)
* @return boolean result
*/
@Override
public void verify(byte[] key, byte[] message, byte[] signature) {
public boolean verify(byte[] key, byte[] message, byte[] signature) {
byte[] authenticate = authenticate(key, message);
for(short i = 0; i < (short)signature.length; i++){
if(authenticate[i] != signature[i])
return false;
}
return true;
}
public byte[] ecdh(byte[] peerKey){
......@@ -103,9 +149,71 @@ public class PinUvAuthProtocolOne extends PinUvAuthProtocol{
keyAgreement.generateSecret(peerKey, (short)0, (short)65, sharedKey, (short)0);
return kdf(sharedKey, (short)1);
}
/**
*
* @param Z shared key from ecdh
* @param offset where the x-coordinate begin
* @return derivative key
*/
public byte[] kdf(byte[] Z, short offset){
byte[] hashed = new byte[32];
sha256.reset();
sha256.doFinal(Z, offset, (short)32, hashed, (short)0);
return hashed;
}
/**
*
* @param pin pin
* @return hashed pin
*/
public byte[] hashPin(byte[] pin){
byte[] hashedPin = new byte[32];
sha256.reset();
sha256.doFinal(pin, (short)0, (short)pin.length, hashedPin, (short)0);
return hashedPin;
}
/**
*
* @param key key must <= 64 bytes
* @param message message must <= 32 bytes
* @return hmac
*/
public byte[] hmac256(byte[] key, byte[] message){
short BLOCKSIZE=64; // 512 bits
short HASHSIZE=32; // 256 bits
byte[] hashed = new byte[HASHSIZE];
byte[] hmacBuffer = new byte[(short)(BLOCKSIZE + hashed.length)];
for (short i=0; i < (short)key.length; i++){
hmacBuffer[i]= (byte) (key[i] ^ (0x36));
}
Util.arrayFillNonAtomic(hmacBuffer, (short)key.length, (short)(BLOCKSIZE-key.length), (byte)0x36); // ipad
Util.arrayCopyNonAtomic(message, (short)0, hmacBuffer, BLOCKSIZE, (short)message.length);
sha256.update(hmacBuffer, (short)0, HASHSIZE);
sha256.update(hmacBuffer, (short)32, HASHSIZE);
sha256.doFinal(hmacBuffer, BLOCKSIZE, (short)(message.length), hashed, (short)0);
for (short i=0; i< (short)key.length; i++){
hmacBuffer[i]= (byte) (key[i] ^ (0x5c));
}
Util.arrayFillNonAtomic(hmacBuffer, (short)key.length, (short)(BLOCKSIZE - key.length), (byte)0x5c); // opad
Util.arrayCopy(hashed, (short)0, hmacBuffer, BLOCKSIZE, (short)hashed.length);
sha256.update(hmacBuffer, (short)0, HASHSIZE);
sha256.update(hmacBuffer, (short)32, HASHSIZE);
sha256.doFinal(hmacBuffer, BLOCKSIZE, (short)(hashed.length), hashed, (short)0);
return hashed;
}
}
......@@ -17,7 +17,6 @@
package com.josh.vku2f;
public class Utf8Strings {
public static final byte[] UTF8_UP = {'u', 'p'};
// Representation of "id" in UTF8
public static final byte[] UTF8_ID = {'i', 'd'};
// Representation of "name" in UTF8
......@@ -26,20 +25,28 @@ public class Utf8Strings {
public static final byte[] UTF8_DISPLAYNAME = {'d', 'i', 's', 'p', 'l', 'a', 'y', 'n', 'a', 'm', 'e'};
// Representation of "alg" in UTF8
public static final byte[] UTF8_ALG = {'a', 'l', 'g'};
public static final byte[] UTF8_UV = {'u', 'v'};
public static final byte[] UTF8_RK = {'r', 'k'};
public static final byte[] UTF8_UP = {'u', 'p'};
public static final byte[] UTF8_UV = {'u', 'v'};
public static final byte[] UTF8_plat = {'p', 'l', 'a', 't'};
public static final byte[] UTF8_CLIENT_PIN = {'c', 'l', 'i', 'e', 'n', 't', 'P', 'i', 'n'};
public static final byte[] UTF8_CREDENTIAL_MGMT_PREVIEW = {'c', 'r', 'e', 'd', 'e', 'n', 't', 'i', 'a', 'l', 'M', 'g', 'm', 't', 'P', 'r', 'e', 'v', 'i', 'e', 'w', };
public static final byte[] UTF8_nfc = {'n', 'f', 'c'};
public static final byte[] UTF8_usb = {'u', 's', 'b'};
public static final byte[] UTF8_TYPE = {'t', 'y', 'p', 'e'};
public static final byte[] UTF8_PACKED = {'p', 'a', 'c', 'k', 'e', 'd'};
public static final byte[] UTF8_SIG = {'s', 'i', 'g'};
public static final byte[] UTF8_X5C = {'x', '5', 'c'};
public static final byte[] UTF8_PUBLIC_KEY = {'p', 'u', 'b', 'l', 'i', 'c', '-', 'k', 'e', 'y'};
public static final byte[] UTF8_U2F_V2 = {'U', '2', 'F', '_', 'V', '2'};
public static final byte[] UTF8_FIDO2 = {'F', 'I', 'D', 'O', '_', '2', '_', '0'};
public static final byte[] UTF8_FIDO_2_1_PRE = {'F', 'I', 'D', 'O', '_', '2', '_', '1', '_', 'P', 'R', 'E'};
public static final byte[] UTF8_ICON = {'i', 'c', 'o', 'n'};
public static final byte[] UTF8_NULL = {'n', 'u', 'l', 'l'};
public static final byte[] UTF8_EXTENSIONS = {'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's'};
public static final byte[] UTF8_PRLab = {'P', 'R', 'L', 'a', 'b'};
public static final byte[] UTF8_credProtect = {'c','r','e','d','P','r','o','t','e','c','t'};
public static final byte[] UTF8_hmac_secret = {'h','m','a','c','-','s','e','c','r','e','t'};
public static final byte[] UTF8_HMAC = {'H', 'M', 'A', 'C'};
public static final byte[] UTF8_Cx = {'C', 'x'};
public static final byte[] UTF8_IDx = {'I', 'D', 'x'};
......
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