Skip to content

Commit

Permalink
Handled merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
Tore Kasper Frederiksen committed Apr 6, 2022
2 parents b38ffc4 + 1979c6d commit d0bf467
Show file tree
Hide file tree
Showing 19 changed files with 275 additions and 163 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ dependencies {
implementation 'org.web3j:core:[4,5.0.0)'
implementation 'com.auth0:java-jwt:[3, 4)'
implementation 'org.json:json:20220320' // To ensure obsolete trulioo code can compile
implementation group: 'com.github.cliftonlabs', name: 'json-simple', version: '[4, 5)'
implementation group: 'com.github.cliftonlabs', name: 'json-simple', version: '[4.0.1, 5)'
implementation group: 'commons-cli', name: 'commons-cli', version: '[1.5.0, 2)'
implementation group: 'com.google.code.gson', name: 'gson', version: '[2.9.0, 3)'
testImplementation 'org.mockito:mockito-core:[4.4.0, 5)'
implementation 'com.fasterxml.jackson.core:jackson-databind:[2.13.2.1,)'
implementation group: 'org.java-websocket', name: 'Java-WebSocket'
implementation group: 'org.java-websocket', name: 'Java-WebSocket', version: '[1.5.2,)'
}

sourceSets {
Expand Down
4 changes: 2 additions & 2 deletions data-modules/output/asn/AuthenticationFramework.asn
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ Validity ::= CHOICE {

ValidityValue ::= SEQUENCE {
notBefore GeneralizedTime,
notBeforeInt INTEGER OPTIONAL, -- NotBefore time since epoch in milliseconds
notBeforeInt INTEGER OPTIONAL, -- NotBefore time since epoch in seconds
notAfter GeneralizedTime,
notAfterInt INTEGER OPTIONAL -- NotAfter time since epoch in milliseconds
notAfterInt INTEGER OPTIONAL -- NotAfter time since epoch in seconds
}

Extensions ::= SEQUENCE OF Extension
Expand Down
4 changes: 2 additions & 2 deletions data-modules/src/AuthenticationFramework.asd
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@
<sequence>
<element name="notBefore" type="asnx:GeneralizedTime"/>
<optional>
<element name="notBeforeInt" type="asnx:INTEGER"/>
<element name="notBeforeInt" type="asnx:INTEGER"/> <!-- time in seconds since epoch -->
</optional>
<element name="notAfter" type="asnx:GeneralizedTime"/>
<optional>
<element name="notAfterInt" type="asnx:INTEGER"/>
<element name="notAfterInt" type="asnx:INTEGER"/> <!-- time in seconds since epoch -->
</optional>
</sequence>
</type>
Expand Down
20 changes: 12 additions & 8 deletions src/main/java/org/tokenscript/attestation/Attestation.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
public class Attestation implements Signable, ASNEncodable, Validateable {
private static final Logger logger = LogManager.getLogger(Attestation.class);
public static final ASN1ObjectIdentifier OID_OCTETSTRING = new ASN1ObjectIdentifier("1.3.6.1.4.1.1466.115.121.1.40");
// TODO should be true, once https://github.com/TokenScript/attestation/pull/237 gets merged
public boolean blockchainFriendly = true;

// Attestation fields
Expand Down Expand Up @@ -91,11 +92,13 @@ public Attestation(byte[] derEncoding) throws IOException, IllegalArgumentExcept
try {
notValidBeforeLong = ASN1Integer.getInstance(validity.getObjectAt(validityCtr)).longValueExact();
validityCtr++;
blockchainFriendly = true;
} catch (IllegalArgumentException e) {
// Optional long timestamp is not included
blockchainFriendly = false;
}
if (notValidBeforeLong != null && notValidBeforeLong != notValidBefore.getTime()) {

if (notValidBeforeLong != null && !notValidBeforeLong.equals(notValidBefore.toInstant().getEpochSecond())) {
logger.error("NotValidBefore integer encoding is inconsistent with the GeneralizedTime encoding");
throw new IllegalArgumentException("NotValidBefore integer encoding is inconsistent with the GeneralizedTime encoding");
}
Expand All @@ -105,11 +108,12 @@ public Attestation(byte[] derEncoding) throws IOException, IllegalArgumentExcept
try {
notValidAfterLong = ASN1Integer.getInstance(validity.getObjectAt(validityCtr)).longValueExact();
validityCtr++;
blockchainFriendly = true;
} catch (IllegalArgumentException|ArrayIndexOutOfBoundsException e) {
// Optional long timestamp is not included
blockchainFriendly = false;
}
if (notValidAfterLong != null && notValidAfterLong != notValidAfter.getTime()) {
if (notValidAfterLong != null && !notValidAfterLong.equals(notValidAfter.toInstant().getEpochSecond())) {
logger.error("NotValidAfter integer encoding is inconsistent with the GeneralizedTime encoding");
throw new IllegalArgumentException("NotValidAfter integer encoding is inconsistent with the GeneralizedTime encoding");
}
Expand Down Expand Up @@ -199,8 +203,8 @@ public Date getNotValidBefore() {
}

public void setNotValidBefore(Date notValidBefore) {
// Remove milliseconds since they are not included in Generalized Time
Date time = new Date(notValidBefore.getTime()-(notValidBefore.getTime() % 1000));
// Convert to milliseconds, rounded down
Date time = new Date(notValidBefore.toInstant().getEpochSecond()*1000);
this.notValidBefore = time;
}

Expand All @@ -209,8 +213,8 @@ public Date getNotValidAfter() {
}

public void setNotValidAfter(Date notValidAfter) {
// Remove milliseconds since they are not included in Generalized Time
Date time = new Date(notValidAfter.getTime()-(notValidAfter.getTime() % 1000));
// Convert to milliseconds, rounded down
Date time = new Date(notValidAfter.toInstant().getEpochSecond()*1000);
this.notValidAfter = time;
}

Expand Down Expand Up @@ -372,11 +376,11 @@ public byte[] getPrehash(boolean blockchainFriendlyEncoding) {
ASN1EncodableVector date = new ASN1EncodableVector();
date.add(new ASN1GeneralizedTime(this.notValidBefore));
if (blockchainFriendlyEncoding) {
date.add(new ASN1Integer(this.notValidBefore.getTime()));
date.add(new ASN1Integer(this.notValidBefore.toInstant().getEpochSecond()));
}
date.add(new ASN1GeneralizedTime(this.notValidAfter));
if (blockchainFriendlyEncoding) {
date.add(new ASN1Integer(this.notValidAfter.getTime()));
date.add(new ASN1Integer(this.notValidAfter.toInstant().getEpochSecond()));
}
res.add(new DERSequence(date));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public class Eip712AttestationRequest extends Eip712Validator implements JsonEnc
private final AsymmetricKeyParameter publicKey;
private final long acceptableTimeLimit;

/**
* For security reasons it should not be possible to accept both legacy and current usage values in the future.
*/
@Deprecated
public static Eip712AttestationRequest decodeAndValidateAttestation(String attestorDomain, String jsonEncoding) {
Eip712AttestationRequest attestationRequest;
try {
Expand Down
97 changes: 73 additions & 24 deletions src/main/javascript/crypto/src/Authenticator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import {Ticket} from "./Ticket";
import {KeyPair} from "./libs/KeyPair";
import {base64ToUint8array, uint8ToBn, uint8tohex, uint8toString, logger} from "./libs/utils";
import {
base64ToUint8array,
uint8ToBn,
uint8tohex,
uint8toString,
logger,
hexStringToBase64Url,
hexStringToBase64
} from "./libs/utils";
import {SignedIdentifierAttestation} from "./libs/SignedIdentifierAttestation";
import {AttestedObject} from "./libs/AttestedObject";
import {XMLconfigData} from "./data/tokenData";
Expand All @@ -20,15 +28,6 @@ import {AttestationRequestWithUsage} from "./libs/AttestationRequestWithUsage";
import {Validateable} from "./libs/Validateable";
import {DEBUGLEVEL} from "./config";

let subtle:any;

if (typeof crypto === "object" && crypto.subtle){
subtle = crypto.subtle;
} else {
subtle = require('crypto').webcrypto.subtle;
}


declare global {
interface Window {
attachEvent: any;
Expand Down Expand Up @@ -64,6 +63,13 @@ interface postMessageData {
force?: boolean,
email?: string,
magicLink?: string,
address?: string,
provider_name?: string,
}

interface WalletMetaData {
address?: string,
wallet?: string,
}

export class Authenticator {
Expand All @@ -81,20 +87,23 @@ export class Authenticator {

private iframe: any;
private iframeWrap: any;
private base64senderPublicKey: string;
private base64senderPublicKeys: {[index: string]: KeyPair};
private base64attestorPubKey: string;

private webDomain: string;
private walletMetaData: WalletMetaData;

private attestationListener: any;

constructor(private negotiator: any = false) {
let XMLconfig = XMLconfigData;

this.base64senderPublicKey = XMLconfig.base64senderPublicKey;
this.base64senderPublicKeys = XMLconfig.base64senderPublicKeys;
this.base64attestorPubKey = XMLconfig.base64attestorPubKey;
this.webDomain = XMLconfig.webDomain;
}

getAuthenticationBlob(tokenObj: devconToken, authResultCallback: Function) {
getAuthenticationBlob(tokenObj: devconToken, walletMetaData:WalletMetaData = {}, authResultCallback: Function) {
// TODO - what is tokenType, where can we see structure etc.
// 1. Find the token type (using TokenScript)
// Oleg: we can avoid Autenticator -> Negotiator request, just have to receive everything in single input object
Expand All @@ -104,6 +113,7 @@ export class Authenticator {
// unless DevCon changed their tokenscript and moved all tickets to the contract

this.signedTokenBlob = tokenObj.ticketBlob;
this.walletMetaData = walletMetaData;
this.magicLink = tokenObj.magicLink;
this.email = tokenObj.email;
this.signedTokenSecret = tokenObj.ticketSecret;
Expand All @@ -119,18 +129,20 @@ export class Authenticator {
getIdentifierAttestation() {
logger(DEBUGLEVEL.HIGH,'getIdentifierAttestation. create iframe with ' + this.attestationOrigin);

this.attestationListener = this.postMessageAttestationListener.bind(this);
// attach postMessage listener and wait for attestation data
this.attachPostMessageListener(this.postMessageAttestationListener.bind(this));
this.attachPostMessageListener(this.attestationListener);
const iframe = document.createElement('iframe');
this.iframe = iframe;
iframe.src = this.attestationOrigin;
iframe.style.width = '800px';
iframe.style.height = '700px';
iframe.style.maxWidth = '100%';
iframe.style.border = 'none';
iframe.style.background = '#fff';
let iframeWrap = document.createElement('div');
this.iframeWrap = iframeWrap;
iframeWrap.setAttribute('style', 'width:100%;min-height: 100vh; position: fixed; align-items: center; justify-content: center;display: none;top: 0; left: 0; background: #fffa');
iframeWrap.setAttribute('style', 'width:100%;min-height: 100vh; position: fixed; align-items: center; justify-content: center;display: none;top: 0; left: 0; background: #000a');
iframeWrap.appendChild(iframe);

document.body.appendChild(iframeWrap);
Expand All @@ -143,15 +155,15 @@ export class Authenticator {
base64ticket: string,
base64attestation: string,
base64attestationPublicKey: string,
base64senderPublicKey: string
base64senderPublicKeys: {[index: string]:KeyPair}
)
{
let ticket: Ticket;
let att: SignedIdentifierAttestation;

// let ticket: Ticket = Ticket.fromBase64(base64ticket, KeyPair.fromPublicHex(base64senderPublicKey));
try {
ticket = Ticket.fromBase64(base64ticket,{"6": KeyPair.publicFromBase64(base64senderPublicKey)});
ticket = Ticket.fromBase64(base64ticket, base64senderPublicKeys);
if (!ticket.checkValidity()) {
logger(DEBUGLEVEL.LOW,"Could not validate ticket");
throw new Error("Validation failed");
Expand Down Expand Up @@ -197,8 +209,11 @@ export class Authenticator {
// let signed = await redeem.sign();

let unSigned = redeem.getDerEncoding();

logger(DEBUGLEVEL.HIGH,unSigned);
return unSigned;
return hexStringToBase64(unSigned);
// return unSigned;

} catch (e) {
logger(DEBUGLEVEL.LOW,'getUseTicket: redeem failed');
logger(DEBUGLEVEL.MEDIUM,e);
Expand All @@ -221,9 +236,27 @@ export class Authenticator {
typeof event.data.ready !== "undefined"
&& event.data.ready === true
) {
logger(DEBUGLEVEL.HIGH,'this.magicLink',this.magicLink);
logger(DEBUGLEVEL.HIGH,'this.email',this.email);

let sendData:postMessageData = {force: false};
if (this.magicLink) sendData.magicLink = this.magicLink;
if (this.email) sendData.email = this.email;
if (this.walletMetaData.address) sendData.address = this.walletMetaData.address;
if (this.walletMetaData.wallet) {
switch (this.walletMetaData.wallet) {
case "Metamask":
sendData.provider_name = "injected";
break;
// case "WalletConnect":
// sendData.provider_name = "injected";
// break;
default:
sendData.force = true;
}
}

logger(DEBUGLEVEL.HIGH,'sendData',sendData);

this.iframe.contentWindow.postMessage(sendData, this.attestationOrigin);
return;
Expand Down Expand Up @@ -255,6 +288,7 @@ export class Authenticator {
) {
return;
}
this.detachPostMessageListener(this.attestationListener);
this.iframeWrap.remove();
this.attestationBlob = event.data.attestation;
this.attestationSecret = event.data.requestSecret;
Expand All @@ -271,16 +305,17 @@ export class Authenticator {
this.signedTokenBlob ,
this.attestationBlob ,
this.base64attestorPubKey,
this.base64senderPublicKey,
this.base64senderPublicKeys,
).then(useToken => {
if (useToken){
logger(DEBUGLEVEL.HIGH,'this.authResultCallback( useToken ): ');
this.authResultCallback(useToken);
} else {
logger(DEBUGLEVEL.HIGH,'this.authResultCallback( empty ): ');
this.authResultCallback(useToken);
}

this.authResultCallback(useToken);
}).catch(e=>{
logger(DEBUGLEVEL.LOW,`UseDevconTicket . Something went wrong. ${e}`);
this.authResultCallback(false);
})


Expand Down Expand Up @@ -314,6 +349,15 @@ export class Authenticator {
}
}

detachPostMessageListener(listener:EventListener) {
if (window.addEventListener) {
window.removeEventListener("message", listener, false);
} else {
// IE8
window.detachEvent("onmessage", listener);
}
}


/*
* get ticket attestation from wallet, or issuer site's local storage through iframe
Expand Down Expand Up @@ -369,16 +413,21 @@ export class Authenticator {
issuerName: string,
validityInMilliseconds: number ,
attestRequestJson: string,
attestorDomain: string ){
attestorDomain: string,
usageValue: string = "" ){
let att: IdentifierAttestation;
let crypto = new AttestationCrypto();
let attestationRequest;
let commitment;

try {
// decode JSON and fill publicKey
// set usageValue as "Creating email attestation"
attestationRequest = new Eip712AttestationRequest();
attestationRequest.setDomain(attestorDomain);
if (usageValue){
attestationRequest.setUsageValue(usageValue);
}
attestationRequest.fillJsonData(attestRequestJson);

Authenticator.checkAttestRequestVerifiability(attestationRequest);
Expand All @@ -395,7 +444,7 @@ export class Authenticator {
Authenticator.checkAttestRequestValidity(attestationRequest);
} catch (e) {
let m = "Failed to parse Eip712AttestationRequestWithUsage. " + e;
logger(DEBUGLEVEL.MEDIUM,m);
logger(DEBUGLEVEL.LOW,m);
logger(DEBUGLEVEL.MEDIUM,e);
throw new Error(m);
}
Expand Down
Loading

0 comments on commit d0bf467

Please sign in to comment.