Skip to content

WIP: feat: remove jsrsasign dependancy #356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"angular-oauth2-oidc": "^2.1.8",
"bootstrap": "^3.3.7",
"core-js": "^2.5.1",
"jsrsasign": "^8.0.12",
"rxjs": "6.1.0",
"rxjs-compat": "^6.0.0-rc.0",
"zone.js": "^0.8.26"
Expand Down Expand Up @@ -63,7 +62,7 @@
"protractor": "~5.2.0",
"ts-node": "~3.3.0",
"tslint": "~5.8.0",
"typescript": "^2.7.2",
"typescript": "2.7.2",
"webpack": "^4.4.1"
}
}
9 changes: 3 additions & 6 deletions projects/lib/ng-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
"dest": "../../dist/lib",
"deleteDestPath": false,
"lib": {
"languageLevel": ["dom", "es2017"],
"entryFile": "src/public_api.ts"
},
"whitelistedNonPeerDependencies": [
"jsrsasign"
]

}
}
}
7 changes: 2 additions & 5 deletions projects/lib/ng-package.prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,5 @@
"dest": "../../dist/lib",
"lib": {
"entryFile": "src/public_api.ts"
},
"whitelistedNonPeerDependencies": [
"jsrsasign"
]
}
}
}
3 changes: 0 additions & 3 deletions projects/lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
},
"version": "4.0.3",
"repository": "manfredsteyer/angular-oauth2-oidc",
"dependencies": {
"jsrsasign": "^8.0.12"
},
"peerDependencies": {
"@angular/common": "^6.0.0",
"@angular/core": "^6.0.0"
Expand Down
45 changes: 25 additions & 20 deletions projects/lib/src/oauth-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1537,26 +1537,31 @@ export class OAuthService extends AuthConfig {
loadKeys: () => this.loadJwks()
};

if (
!this.disableAtHashCheck &&
this.requestAccessToken &&
!this.checkAtHash(validationParams)
) {
const err = 'Wrong at_hash';
this.logger.warn(err);
return Promise.reject(err);
}

return this.checkSignature(validationParams).then(_ => {
const result: ParsedIdToken = {
idToken: idToken,
idTokenClaims: claims,
idTokenClaimsJson: claimsJson,
idTokenHeader: header,
idTokenHeaderJson: headerJson,
idTokenExpiresAt: expiresAtMSec
};
return result;
return this.checkAtHash(validationParams)
.then(atHashValid => {
if (
!this.disableAtHashCheck &&
this.requestAccessToken &&
!atHashValid
) {
const err = 'Wrong at_hash';
this.logger.warn(err);
return Promise.reject(err);
}

return this.checkSignature(validationParams).then(_ => {
const result: ParsedIdToken = {
idToken: idToken,
idTokenClaims: claims,
idTokenClaimsJson: claimsJson,
idTokenHeader: header,
idTokenHeaderJson: headerJson,
idTokenExpiresAt: expiresAtMSec
};
return result;
});

});
}

Expand Down Expand Up @@ -1782,7 +1787,7 @@ export class OAuthService extends AuthConfig {
});
}

private checkAtHash(params: ValidationParams): boolean {
private async checkAtHash(params: ValidationParams): Promise<boolean> {
if (!this.tokenValidationHandler) {
this.logger.warn(
'No tokenValidationHandler configured. Cannot check at_hash.'
Expand Down
41 changes: 18 additions & 23 deletions projects/lib/src/token-validation/jwks-validation-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
ValidationParams
} from './validation-handler';

import * as rs from 'jsrsasign';

/**
* Validates the signature of an id_token against one
* of the keys of an JSON Web Key Set (jwks).
Expand Down Expand Up @@ -35,7 +33,10 @@ export class JwksValidationHandler extends AbstractValidationHandler {
*/
gracePeriodInSec = 600;

validateSignature(params: ValidationParams, retry = false): Promise<any> {
private cyptoObj: Crypto = window.crypto || (window as any).msCrypto // for IE11
private textEncoder = new (window as any).TextEncoder();

async validateSignature(params: ValidationParams, retry = false): Promise<any> {
if (!params.idToken) throw new Error('Parameter idToken expected!');
if (!params.idTokenHeader)
throw new Error('Parameter idTokenHandler expected.');
Expand All @@ -50,8 +51,8 @@ export class JwksValidationHandler extends AbstractValidationHandler {
}

let kid: string = params.idTokenHeader['kid'];
let keys: object[] = params.jwks['keys'];
let key: object;
let keys: JsonWebKey[] = params.jwks['keys'];
let key: JsonWebKey;

let alg = params.idTokenHeader['alg'];

Expand Down Expand Up @@ -98,20 +99,14 @@ export class JwksValidationHandler extends AbstractValidationHandler {
return Promise.reject(error);
}

let keyObj = rs.KEYUTIL.getKey(key);
let validationOptions = {
alg: this.allowedAlgorithms,
gracePeriod: this.gracePeriodInSec
};
let isValid = rs.KJUR.jws.JWS.verifyJWT(
params.idToken,
keyObj,
validationOptions
);

if (isValid) {
const [header, body, sig] = params.idToken.split(',');

const cyptokey = await this.cyptoObj.subtle.importKey('jwk', key as any, alg, true, ['verify']);
const isValid = await this.cyptoObj.subtle.verify(alg, cyptokey, this.textEncoder.encode(sig), this.textEncoder.encode(body));

if(isValid) {
return Promise.resolve();
} else {
}else {
return Promise.reject('Signature not valid');
}
}
Expand All @@ -127,11 +122,11 @@ export class JwksValidationHandler extends AbstractValidationHandler {
}
}

calcHash(valueToHash: string, algorithm: string): string {
let hashAlg = new rs.KJUR.crypto.MessageDigest({ alg: algorithm });
let result = hashAlg.digestString(valueToHash);
let byteArrayAsString = this.toByteArrayAsString(result);
return byteArrayAsString;
async calcHash(valueToHash: string, algorithm: string): Promise<string> {
const valueAsBytes = this.textEncoder.encode(valueToHash);
const resultBytes = await this.cyptoObj.subtle.digest(algorithm, valueAsBytes);
// the returned bytes are encoded as UTF-16
return String.fromCharCode.apply(null, new Uint16Array(resultBytes));
}

toByteArrayAsString(hexString: string) {
Expand Down
4 changes: 2 additions & 2 deletions projects/lib/src/token-validation/null-validation-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class NullValidationHandler implements ValidationHandler {
validateSignature(validationParams: ValidationParams): Promise<any> {
return Promise.resolve(null);
}
validateAtHash(validationParams: ValidationParams): boolean {
return true;
validateAtHash(validationParams: ValidationParams): Promise<boolean> {
return Promise.resolve(true);
}
}
79 changes: 0 additions & 79 deletions projects/lib/src/token-validation/validation-handler.js

This file was deleted.

8 changes: 4 additions & 4 deletions projects/lib/src/token-validation/validation-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export abstract class ValidationHandler {
/**
* Validates the at_hash in an id_token against the received access_token.
*/
public abstract validateAtHash(validationParams: ValidationParams): boolean;
public abstract validateAtHash(validationParams: ValidationParams): Promise<boolean>;
}

/**
Expand All @@ -39,10 +39,10 @@ export abstract class AbstractValidationHandler implements ValidationHandler {
/**
* Validates the at_hash in an id_token against the received access_token.
*/
validateAtHash(params: ValidationParams): boolean {
async validateAtHash(params: ValidationParams): Promise<boolean> {
let hashAlg = this.inferHashAlgorithm(params.idTokenHeader);

let tokenHash = this.calcHash(params.accessToken, hashAlg); // sha256(accessToken, { asString: true });
let tokenHash = await this.calcHash(params.accessToken, hashAlg); // sha256(accessToken, { asString: true });

let leftMostHalf = tokenHash.substr(0, tokenHash.length / 2);

Expand Down Expand Up @@ -85,5 +85,5 @@ export abstract class AbstractValidationHandler implements ValidationHandler {
* @param valueToHash
* @param algorithm
*/
protected abstract calcHash(valueToHash: string, algorithm: string): string;
protected abstract calcHash(valueToHash: string, algorithm: string): Promise<string>;
}
Loading