Skip to content

Commit f49190e

Browse files
Merge pull request #356 from Toxicable/master
WIP: feat: remove jsrsasign dependancy
2 parents 7c752e5 + 846415f commit f49190e

10 files changed

+7846
-144
lines changed

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
"angular-oauth2-oidc": "^2.1.8",
3434
"bootstrap": "^3.3.7",
3535
"core-js": "^2.5.1",
36-
"jsrsasign": "^8.0.12",
3736
"rxjs": "6.1.0",
3837
"rxjs-compat": "^6.0.0-rc.0",
3938
"zone.js": "^0.8.26"
@@ -63,7 +62,7 @@
6362
"protractor": "~5.2.0",
6463
"ts-node": "~3.3.0",
6564
"tslint": "~5.8.0",
66-
"typescript": "^2.7.2",
65+
"typescript": "2.7.2",
6766
"webpack": "^4.4.1"
6867
}
6968
}

projects/lib/ng-package.json

+3-6
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
"dest": "../../dist/lib",
44
"deleteDestPath": false,
55
"lib": {
6+
"languageLevel": ["dom", "es2017"],
67
"entryFile": "src/public_api.ts"
7-
},
8-
"whitelistedNonPeerDependencies": [
9-
"jsrsasign"
10-
]
11-
12-
}
8+
}
9+
}

projects/lib/ng-package.prod.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,5 @@
33
"dest": "../../dist/lib",
44
"lib": {
55
"entryFile": "src/public_api.ts"
6-
},
7-
"whitelistedNonPeerDependencies": [
8-
"jsrsasign"
9-
]
10-
}
6+
}
7+
}

projects/lib/package.json

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
},
77
"version": "4.0.3",
88
"repository": "manfredsteyer/angular-oauth2-oidc",
9-
"dependencies": {
10-
"jsrsasign": "^8.0.12"
11-
},
129
"peerDependencies": {
1310
"@angular/common": "^6.0.0",
1411
"@angular/core": "^6.0.0"

projects/lib/src/oauth-service.ts

+25-20
Original file line numberDiff line numberDiff line change
@@ -1537,26 +1537,31 @@ export class OAuthService extends AuthConfig {
15371537
loadKeys: () => this.loadJwks()
15381538
};
15391539

1540-
if (
1541-
!this.disableAtHashCheck &&
1542-
this.requestAccessToken &&
1543-
!this.checkAtHash(validationParams)
1544-
) {
1545-
const err = 'Wrong at_hash';
1546-
this.logger.warn(err);
1547-
return Promise.reject(err);
1548-
}
15491540

1550-
return this.checkSignature(validationParams).then(_ => {
1551-
const result: ParsedIdToken = {
1552-
idToken: idToken,
1553-
idTokenClaims: claims,
1554-
idTokenClaimsJson: claimsJson,
1555-
idTokenHeader: header,
1556-
idTokenHeaderJson: headerJson,
1557-
idTokenExpiresAt: expiresAtMSec
1558-
};
1559-
return result;
1541+
return this.checkAtHash(validationParams)
1542+
.then(atHashValid => {
1543+
if (
1544+
!this.disableAtHashCheck &&
1545+
this.requestAccessToken &&
1546+
!atHashValid
1547+
) {
1548+
const err = 'Wrong at_hash';
1549+
this.logger.warn(err);
1550+
return Promise.reject(err);
1551+
}
1552+
1553+
return this.checkSignature(validationParams).then(_ => {
1554+
const result: ParsedIdToken = {
1555+
idToken: idToken,
1556+
idTokenClaims: claims,
1557+
idTokenClaimsJson: claimsJson,
1558+
idTokenHeader: header,
1559+
idTokenHeaderJson: headerJson,
1560+
idTokenExpiresAt: expiresAtMSec
1561+
};
1562+
return result;
1563+
});
1564+
15601565
});
15611566
}
15621567

@@ -1782,7 +1787,7 @@ export class OAuthService extends AuthConfig {
17821787
});
17831788
}
17841789

1785-
private checkAtHash(params: ValidationParams): boolean {
1790+
private async checkAtHash(params: ValidationParams): Promise<boolean> {
17861791
if (!this.tokenValidationHandler) {
17871792
this.logger.warn(
17881793
'No tokenValidationHandler configured. Cannot check at_hash.'

projects/lib/src/token-validation/jwks-validation-handler.ts

+18-23
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import {
33
ValidationParams
44
} from './validation-handler';
55

6-
import * as rs from 'jsrsasign';
7-
86
/**
97
* Validates the signature of an id_token against one
108
* of the keys of an JSON Web Key Set (jwks).
@@ -35,7 +33,10 @@ export class JwksValidationHandler extends AbstractValidationHandler {
3533
*/
3634
gracePeriodInSec = 600;
3735

38-
validateSignature(params: ValidationParams, retry = false): Promise<any> {
36+
private cyptoObj: Crypto = window.crypto || (window as any).msCrypto // for IE11
37+
private textEncoder = new (window as any).TextEncoder();
38+
39+
async validateSignature(params: ValidationParams, retry = false): Promise<any> {
3940
if (!params.idToken) throw new Error('Parameter idToken expected!');
4041
if (!params.idTokenHeader)
4142
throw new Error('Parameter idTokenHandler expected.');
@@ -50,8 +51,8 @@ export class JwksValidationHandler extends AbstractValidationHandler {
5051
}
5152

5253
let kid: string = params.idTokenHeader['kid'];
53-
let keys: object[] = params.jwks['keys'];
54-
let key: object;
54+
let keys: JsonWebKey[] = params.jwks['keys'];
55+
let key: JsonWebKey;
5556

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

@@ -98,20 +99,14 @@ export class JwksValidationHandler extends AbstractValidationHandler {
9899
return Promise.reject(error);
99100
}
100101

101-
let keyObj = rs.KEYUTIL.getKey(key);
102-
let validationOptions = {
103-
alg: this.allowedAlgorithms,
104-
gracePeriod: this.gracePeriodInSec
105-
};
106-
let isValid = rs.KJUR.jws.JWS.verifyJWT(
107-
params.idToken,
108-
keyObj,
109-
validationOptions
110-
);
111-
112-
if (isValid) {
102+
const [header, body, sig] = params.idToken.split(',');
103+
104+
const cyptokey = await this.cyptoObj.subtle.importKey('jwk', key as any, alg, true, ['verify']);
105+
const isValid = await this.cyptoObj.subtle.verify(alg, cyptokey, this.textEncoder.encode(sig), this.textEncoder.encode(body));
106+
107+
if(isValid) {
113108
return Promise.resolve();
114-
} else {
109+
}else {
115110
return Promise.reject('Signature not valid');
116111
}
117112
}
@@ -127,11 +122,11 @@ export class JwksValidationHandler extends AbstractValidationHandler {
127122
}
128123
}
129124

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

137132
toByteArrayAsString(hexString: string) {

projects/lib/src/token-validation/null-validation-handler.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class NullValidationHandler implements ValidationHandler {
88
validateSignature(validationParams: ValidationParams): Promise<any> {
99
return Promise.resolve(null);
1010
}
11-
validateAtHash(validationParams: ValidationParams): boolean {
12-
return true;
11+
validateAtHash(validationParams: ValidationParams): Promise<boolean> {
12+
return Promise.resolve(true);
1313
}
1414
}

projects/lib/src/token-validation/validation-handler.js

-79
This file was deleted.

projects/lib/src/token-validation/validation-handler.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export abstract class ValidationHandler {
2222
/**
2323
* Validates the at_hash in an id_token against the received access_token.
2424
*/
25-
public abstract validateAtHash(validationParams: ValidationParams): boolean;
25+
public abstract validateAtHash(validationParams: ValidationParams): Promise<boolean>;
2626
}
2727

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

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

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

@@ -85,5 +85,5 @@ export abstract class AbstractValidationHandler implements ValidationHandler {
8585
* @param valueToHash
8686
* @param algorithm
8787
*/
88-
protected abstract calcHash(valueToHash: string, algorithm: string): string;
88+
protected abstract calcHash(valueToHash: string, algorithm: string): Promise<string>;
8989
}

0 commit comments

Comments
 (0)