@lindorm/aegis 0.4.4 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/__tests__/jwt-interop.test.ts +13 -10
- package/dist/classes/Aegis.d.ts +13 -20
- package/dist/classes/Aegis.d.ts.map +1 -1
- package/dist/classes/Aegis.js +32 -118
- package/dist/classes/Aegis.js.map +1 -1
- package/dist/classes/JweKit.d.ts +1 -0
- package/dist/classes/JweKit.d.ts.map +1 -1
- package/dist/classes/JweKit.js +56 -9
- package/dist/classes/JweKit.js.map +1 -1
- package/dist/classes/JwsKit.d.ts +1 -0
- package/dist/classes/JwsKit.d.ts.map +1 -1
- package/dist/classes/JwsKit.js +50 -10
- package/dist/classes/JwsKit.js.map +1 -1
- package/dist/classes/JwtKit.d.ts +2 -0
- package/dist/classes/JwtKit.d.ts.map +1 -1
- package/dist/classes/JwtKit.js +83 -10
- package/dist/classes/JwtKit.js.map +1 -1
- package/dist/classes/index.d.ts +0 -3
- package/dist/classes/index.d.ts.map +1 -1
- package/dist/classes/index.js +0 -3
- package/dist/classes/index.js.map +1 -1
- package/dist/constants/token-type.d.ts +6 -0
- package/dist/constants/token-type.d.ts.map +1 -0
- package/dist/constants/token-type.js +20 -0
- package/dist/constants/token-type.js.map +1 -0
- package/dist/errors/index.d.ts +0 -3
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +0 -3
- package/dist/errors/index.js.map +1 -1
- package/dist/guards/index.d.ts +3 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/{types/cws → guards}/index.js +2 -4
- package/dist/guards/index.js.map +1 -0
- package/dist/guards/is-parsed-jws.d.ts +3 -0
- package/dist/guards/is-parsed-jws.d.ts.map +1 -0
- package/dist/guards/is-parsed-jws.js +6 -0
- package/dist/guards/is-parsed-jws.js.map +1 -0
- package/dist/guards/is-parsed-jwt.d.ts +3 -0
- package/dist/guards/is-parsed-jwt.d.ts.map +1 -0
- package/dist/guards/is-parsed-jwt.js +6 -0
- package/dist/guards/is-parsed-jwt.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/Aegis.d.ts +8 -22
- package/dist/interfaces/Aegis.d.ts.map +1 -1
- package/dist/interfaces/index.d.ts +0 -3
- package/dist/interfaces/index.d.ts.map +1 -1
- package/dist/interfaces/index.js +0 -3
- package/dist/interfaces/index.js.map +1 -1
- package/dist/internal/constants/aegis-profile-keys.d.ts +2 -0
- package/dist/internal/constants/aegis-profile-keys.d.ts.map +1 -0
- package/dist/internal/constants/aegis-profile-keys.js +37 -0
- package/dist/internal/constants/aegis-profile-keys.js.map +1 -0
- package/dist/internal/constants/header.d.ts +1 -1
- package/dist/internal/constants/header.d.ts.map +1 -1
- package/dist/internal/constants/header.js +0 -4
- package/dist/internal/constants/header.js.map +1 -1
- package/dist/internal/utils/compute-jwk-thumbprint.d.ts +4 -0
- package/dist/internal/utils/compute-jwk-thumbprint.d.ts.map +1 -0
- package/dist/internal/utils/compute-jwk-thumbprint.js +25 -0
- package/dist/internal/utils/compute-jwk-thumbprint.js.map +1 -0
- package/dist/internal/utils/compute-typ-header.d.ts +7 -0
- package/dist/internal/utils/compute-typ-header.d.ts.map +1 -0
- package/dist/internal/utils/compute-typ-header.js +68 -0
- package/dist/internal/utils/compute-typ-header.js.map +1 -0
- package/dist/internal/utils/extract-aegis-profile.d.ts +7 -0
- package/dist/internal/utils/extract-aegis-profile.d.ts.map +1 -0
- package/dist/internal/utils/extract-aegis-profile.js +34 -0
- package/dist/internal/utils/extract-aegis-profile.js.map +1 -0
- package/dist/internal/utils/extract-claims.d.ts +15 -0
- package/dist/internal/utils/extract-claims.d.ts.map +1 -0
- package/dist/internal/utils/extract-claims.js +201 -0
- package/dist/internal/utils/extract-claims.js.map +1 -0
- package/dist/internal/utils/extract-token-delegation.d.ts +6 -0
- package/dist/internal/utils/extract-token-delegation.d.ts.map +1 -0
- package/dist/internal/utils/extract-token-delegation.js +28 -0
- package/dist/internal/utils/extract-token-delegation.js.map +1 -0
- package/dist/internal/utils/generate-token-id.d.ts +2 -0
- package/dist/internal/utils/generate-token-id.d.ts.map +1 -0
- package/dist/internal/utils/generate-token-id.js +9 -0
- package/dist/internal/utils/generate-token-id.js.map +1 -0
- package/dist/internal/utils/jose-header.d.ts +2 -2
- package/dist/internal/utils/jose-header.d.ts.map +1 -1
- package/dist/internal/utils/jose-header.js +5 -5
- package/dist/internal/utils/jose-header.js.map +1 -1
- package/dist/internal/utils/jwt-payload.d.ts.map +1 -1
- package/dist/internal/utils/jwt-payload.js +50 -43
- package/dist/internal/utils/jwt-payload.js.map +1 -1
- package/dist/internal/utils/jwt-verify.d.ts.map +1 -1
- package/dist/internal/utils/jwt-verify.js +30 -6
- package/dist/internal/utils/jwt-verify.js.map +1 -1
- package/dist/internal/utils/parse-introspection.d.ts +7 -0
- package/dist/internal/utils/parse-introspection.d.ts.map +1 -0
- package/dist/internal/utils/parse-introspection.js +28 -0
- package/dist/internal/utils/parse-introspection.js.map +1 -0
- package/dist/internal/utils/parse-userinfo.d.ts +5 -0
- package/dist/internal/utils/parse-userinfo.d.ts.map +1 -0
- package/dist/internal/utils/parse-userinfo.js +26 -0
- package/dist/internal/utils/parse-userinfo.js.map +1 -0
- package/dist/internal/utils/resolve-cert-binding.d.ts +4 -0
- package/dist/internal/utils/resolve-cert-binding.d.ts.map +1 -0
- package/dist/internal/utils/resolve-cert-binding.js +30 -0
- package/dist/internal/utils/resolve-cert-binding.js.map +1 -0
- package/dist/internal/utils/token-header.d.ts +2 -2
- package/dist/internal/utils/token-header.d.ts.map +1 -1
- package/dist/internal/utils/token-header.js +5 -16
- package/dist/internal/utils/token-header.js.map +1 -1
- package/dist/internal/utils/validate-actor.d.ts +3 -0
- package/dist/internal/utils/validate-actor.d.ts.map +1 -0
- package/dist/internal/utils/validate-actor.js +27 -0
- package/dist/internal/utils/validate-actor.js.map +1 -0
- package/dist/internal/utils/validate-crit.d.ts +4 -0
- package/dist/internal/utils/validate-crit.d.ts.map +1 -0
- package/dist/internal/utils/validate-crit.js +55 -0
- package/dist/internal/utils/validate-crit.js.map +1 -0
- package/dist/internal/utils/verify-cert-binding.d.ts +14 -0
- package/dist/internal/utils/verify-cert-binding.d.ts.map +1 -0
- package/dist/internal/utils/verify-cert-binding.js +25 -0
- package/dist/internal/utils/verify-cert-binding.js.map +1 -0
- package/dist/internal/utils/verify-dpop-proof.d.ts +10 -0
- package/dist/internal/utils/verify-dpop-proof.d.ts.map +1 -0
- package/dist/internal/utils/verify-dpop-proof.js +76 -0
- package/dist/internal/utils/verify-dpop-proof.js.map +1 -0
- package/dist/mocks/create-mock-aegis.d.ts +2 -1
- package/dist/mocks/create-mock-aegis.d.ts.map +1 -1
- package/dist/mocks/create-mock-aegis.js +49 -75
- package/dist/mocks/create-mock-aegis.js.map +1 -1
- package/dist/mocks/index.d.ts +1 -1
- package/dist/mocks/index.d.ts.map +1 -1
- package/dist/mocks/index.js +3 -15
- package/dist/mocks/index.js.map +1 -1
- package/dist/types/aegis.d.ts +3 -0
- package/dist/types/aegis.d.ts.map +1 -1
- package/dist/types/claims/act-claim.d.ts +8 -0
- package/dist/types/claims/act-claim.d.ts.map +1 -0
- package/dist/{interfaces/CwtKit.js → types/claims/act-claim.js} +1 -1
- package/dist/types/claims/act-claim.js.map +1 -0
- package/dist/types/claims/aegis-introspection.d.ts +16 -0
- package/dist/types/claims/aegis-introspection.d.ts.map +1 -0
- package/dist/types/claims/aegis-introspection.js +3 -0
- package/dist/types/claims/aegis-introspection.js.map +1 -0
- package/dist/types/claims/aegis-profile.d.ts +44 -0
- package/dist/types/claims/aegis-profile.d.ts.map +1 -0
- package/dist/types/claims/aegis-profile.js +3 -0
- package/dist/types/claims/aegis-profile.js.map +1 -0
- package/dist/types/claims/aegis-userinfo.d.ts +5 -0
- package/dist/types/claims/aegis-userinfo.d.ts.map +1 -0
- package/dist/types/claims/aegis-userinfo.js +3 -0
- package/dist/types/claims/aegis-userinfo.js.map +1 -0
- package/dist/types/claims/confirmation-claim.d.ts +9 -0
- package/dist/types/claims/confirmation-claim.d.ts.map +1 -0
- package/dist/types/claims/confirmation-claim.js +3 -0
- package/dist/types/claims/confirmation-claim.js.map +1 -0
- package/dist/types/claims/delegation-claims.d.ts +6 -0
- package/dist/types/claims/delegation-claims.d.ts.map +1 -0
- package/dist/types/claims/delegation-claims.js +3 -0
- package/dist/types/claims/delegation-claims.js.map +1 -0
- package/dist/types/claims/index.d.ts +13 -0
- package/dist/types/claims/index.d.ts.map +1 -0
- package/dist/types/{cwt → claims}/index.js +12 -7
- package/dist/types/claims/index.js.map +1 -0
- package/dist/types/claims/jwt/act-claim-wire.d.ts +8 -0
- package/dist/types/claims/jwt/act-claim-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/act-claim-wire.js +3 -0
- package/dist/types/claims/jwt/act-claim-wire.js.map +1 -0
- package/dist/types/claims/jwt/confirmation-claim-wire.d.ts +9 -0
- package/dist/types/claims/jwt/confirmation-claim-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/confirmation-claim-wire.js +3 -0
- package/dist/types/claims/jwt/confirmation-claim-wire.js.map +1 -0
- package/dist/types/claims/jwt/delegation-claims-wire.d.ts +6 -0
- package/dist/types/claims/jwt/delegation-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/delegation-claims-wire.js +3 -0
- package/dist/types/claims/jwt/delegation-claims-wire.js.map +1 -0
- package/dist/types/claims/jwt/index.d.ts +10 -0
- package/dist/types/claims/jwt/index.d.ts.map +1 -0
- package/dist/types/{cwe → claims/jwt}/index.js +9 -4
- package/dist/types/claims/jwt/index.js.map +1 -0
- package/dist/types/claims/jwt/jwt-claims.d.ts +8 -0
- package/dist/types/claims/jwt/jwt-claims.d.ts.map +1 -0
- package/dist/types/claims/jwt/jwt-claims.js.map +1 -0
- package/dist/types/claims/jwt/lindorm-claims-wire.d.ts +16 -0
- package/dist/types/claims/jwt/lindorm-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/lindorm-claims-wire.js +3 -0
- package/dist/types/claims/jwt/lindorm-claims-wire.js.map +1 -0
- package/dist/types/claims/jwt/oauth-claims-wire.d.ts +6 -0
- package/dist/types/claims/jwt/oauth-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/oauth-claims-wire.js +3 -0
- package/dist/types/claims/jwt/oauth-claims-wire.js.map +1 -0
- package/dist/types/claims/jwt/oidc-claims-wire.d.ts +11 -0
- package/dist/types/claims/jwt/oidc-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/oidc-claims-wire.js +3 -0
- package/dist/types/claims/jwt/oidc-claims-wire.js.map +1 -0
- package/dist/types/claims/jwt/pop-claims-wire.d.ts +5 -0
- package/dist/types/claims/jwt/pop-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/pop-claims-wire.js +3 -0
- package/dist/types/claims/jwt/pop-claims-wire.js.map +1 -0
- package/dist/types/claims/jwt/std-claims-wire.d.ts +10 -0
- package/dist/types/claims/jwt/std-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/std-claims-wire.js +3 -0
- package/dist/types/claims/jwt/std-claims-wire.js.map +1 -0
- package/dist/types/claims/lindorm-claims.d.ts +18 -0
- package/dist/types/claims/lindorm-claims.d.ts.map +1 -0
- package/dist/types/claims/lindorm-claims.js +3 -0
- package/dist/types/claims/lindorm-claims.js.map +1 -0
- package/dist/types/claims/oauth-claims.d.ts +6 -0
- package/dist/types/claims/oauth-claims.d.ts.map +1 -0
- package/dist/types/claims/oauth-claims.js +3 -0
- package/dist/types/claims/oauth-claims.js.map +1 -0
- package/dist/types/claims/oidc-claims.d.ts +11 -0
- package/dist/types/claims/oidc-claims.d.ts.map +1 -0
- package/dist/types/{cose-target.js → claims/oidc-claims.js} +1 -1
- package/dist/types/claims/oidc-claims.js.map +1 -0
- package/dist/types/claims/pop-claims.d.ts +5 -0
- package/dist/types/claims/pop-claims.d.ts.map +1 -0
- package/dist/types/{cwe/cwe-decode.js → claims/pop-claims.js} +1 -1
- package/dist/types/claims/pop-claims.js.map +1 -0
- package/dist/types/claims/std-claims.d.ts +10 -0
- package/dist/types/claims/std-claims.d.ts.map +1 -0
- package/dist/types/claims/std-claims.js +3 -0
- package/dist/types/claims/std-claims.js.map +1 -0
- package/dist/types/header.d.ts +14 -7
- package/dist/types/header.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -4
- package/dist/types/index.js.map +1 -1
- package/dist/types/jwe/jwe-decrypt.d.ts +2 -4
- package/dist/types/jwe/jwe-decrypt.d.ts.map +1 -1
- package/dist/types/jwe/jwe-encrypt.d.ts +4 -1
- package/dist/types/jwe/jwe-encrypt.d.ts.map +1 -1
- package/dist/types/jwe/jwe-kit.d.ts +2 -7
- package/dist/types/jwe/jwe-kit.d.ts.map +1 -1
- package/dist/types/jws/jws-kit.d.ts +2 -6
- package/dist/types/jws/jws-kit.d.ts.map +1 -1
- package/dist/types/jws/jws-parse.d.ts +2 -5
- package/dist/types/jws/jws-parse.d.ts.map +1 -1
- package/dist/types/jws/jws-sign.d.ts +5 -2
- package/dist/types/jws/jws-sign.d.ts.map +1 -1
- package/dist/types/jwt/index.d.ts +3 -1
- package/dist/types/jwt/index.d.ts.map +1 -1
- package/dist/types/jwt/index.js +3 -1
- package/dist/types/jwt/index.js.map +1 -1
- package/dist/types/jwt/jwt-claim-matchers.d.ts +28 -0
- package/dist/types/jwt/jwt-claim-matchers.d.ts.map +1 -0
- package/dist/types/jwt/jwt-claim-matchers.js +3 -0
- package/dist/types/jwt/jwt-claim-matchers.js.map +1 -0
- package/dist/types/jwt/jwt-decode.d.ts +1 -1
- package/dist/types/jwt/jwt-decode.d.ts.map +1 -1
- package/dist/types/jwt/jwt-delegation.d.ts +7 -0
- package/dist/types/jwt/jwt-delegation.d.ts.map +1 -0
- package/dist/types/jwt/jwt-delegation.js +3 -0
- package/dist/types/jwt/jwt-delegation.js.map +1 -0
- package/dist/types/jwt/jwt-dpop.d.ts +10 -0
- package/dist/types/jwt/jwt-dpop.d.ts.map +1 -0
- package/dist/{interfaces/CwsKit.js → types/jwt/jwt-dpop.js} +1 -1
- package/dist/types/jwt/jwt-dpop.js.map +1 -0
- package/dist/types/jwt/jwt-kit.d.ts +3 -5
- package/dist/types/jwt/jwt-kit.d.ts.map +1 -1
- package/dist/types/jwt/jwt-parse.d.ts +11 -27
- package/dist/types/jwt/jwt-parse.d.ts.map +1 -1
- package/dist/types/jwt/jwt-sign.d.ts +6 -23
- package/dist/types/jwt/jwt-sign.d.ts.map +1 -1
- package/dist/types/jwt/jwt-validate.d.ts +2 -23
- package/dist/types/jwt/jwt-validate.d.ts.map +1 -1
- package/dist/types/jwt/jwt-verify.d.ts +13 -25
- package/dist/types/jwt/jwt-verify.d.ts.map +1 -1
- package/dist/types/kit.d.ts +12 -0
- package/dist/types/kit.d.ts.map +1 -0
- package/dist/{interfaces/CweKit.js → types/kit.js} +1 -1
- package/dist/types/kit.js.map +1 -0
- package/dist/types/level-of-assurance.d.ts +1 -1
- package/dist/types/level-of-assurance.d.ts.map +1 -1
- package/package.json +19 -18
- package/__tests__/cose-interop.test.ts +0 -1127
- package/dist/classes/CweKit.d.ts +0 -14
- package/dist/classes/CweKit.d.ts.map +0 -1
- package/dist/classes/CweKit.js +0 -151
- package/dist/classes/CweKit.js.map +0 -1
- package/dist/classes/CwsKit.d.ts +0 -13
- package/dist/classes/CwsKit.d.ts.map +0 -1
- package/dist/classes/CwsKit.js +0 -139
- package/dist/classes/CwsKit.js.map +0 -1
- package/dist/classes/CwtKit.d.ts +0 -17
- package/dist/classes/CwtKit.d.ts.map +0 -1
- package/dist/classes/CwtKit.js +0 -166
- package/dist/classes/CwtKit.js.map +0 -1
- package/dist/errors/CoseEncryptError.d.ts +0 -4
- package/dist/errors/CoseEncryptError.d.ts.map +0 -1
- package/dist/errors/CoseEncryptError.js +0 -8
- package/dist/errors/CoseEncryptError.js.map +0 -1
- package/dist/errors/CoseSignError.d.ts +0 -4
- package/dist/errors/CoseSignError.d.ts.map +0 -1
- package/dist/errors/CoseSignError.js +0 -8
- package/dist/errors/CoseSignError.js.map +0 -1
- package/dist/errors/CwtError.d.ts +0 -4
- package/dist/errors/CwtError.d.ts.map +0 -1
- package/dist/errors/CwtError.js +0 -8
- package/dist/errors/CwtError.js.map +0 -1
- package/dist/interfaces/CweKit.d.ts +0 -6
- package/dist/interfaces/CweKit.d.ts.map +0 -1
- package/dist/interfaces/CweKit.js.map +0 -1
- package/dist/interfaces/CwsKit.d.ts +0 -6
- package/dist/interfaces/CwsKit.d.ts.map +0 -1
- package/dist/interfaces/CwsKit.js.map +0 -1
- package/dist/interfaces/CwtKit.d.ts +0 -7
- package/dist/interfaces/CwtKit.d.ts.map +0 -1
- package/dist/interfaces/CwtKit.js.map +0 -1
- package/dist/internal/constants/cose.d.ts +0 -19
- package/dist/internal/constants/cose.d.ts.map +0 -1
- package/dist/internal/constants/cose.js +0 -116
- package/dist/internal/constants/cose.js.map +0 -1
- package/dist/internal/utils/auth-tag-length.d.ts +0 -3
- package/dist/internal/utils/auth-tag-length.d.ts.map +0 -1
- package/dist/internal/utils/auth-tag-length.js +0 -21
- package/dist/internal/utils/auth-tag-length.js.map +0 -1
- package/dist/internal/utils/cose/bstr.d.ts +0 -4
- package/dist/internal/utils/cose/bstr.d.ts.map +0 -1
- package/dist/internal/utils/cose/bstr.js +0 -18
- package/dist/internal/utils/cose/bstr.js.map +0 -1
- package/dist/internal/utils/cose/claims.d.ts +0 -5
- package/dist/internal/utils/cose/claims.d.ts.map +0 -1
- package/dist/internal/utils/cose/claims.js +0 -57
- package/dist/internal/utils/cose/claims.js.map +0 -1
- package/dist/internal/utils/cose/crit.d.ts +0 -3
- package/dist/internal/utils/cose/crit.d.ts.map +0 -1
- package/dist/internal/utils/cose/crit.js +0 -43
- package/dist/internal/utils/cose/crit.js.map +0 -1
- package/dist/internal/utils/cose/find.d.ts +0 -5
- package/dist/internal/utils/cose/find.d.ts.map +0 -1
- package/dist/internal/utils/cose/find.js +0 -37
- package/dist/internal/utils/cose/find.js.map +0 -1
- package/dist/internal/utils/cose/header.d.ts +0 -5
- package/dist/internal/utils/cose/header.d.ts.map +0 -1
- package/dist/internal/utils/cose/header.js +0 -81
- package/dist/internal/utils/cose/header.js.map +0 -1
- package/dist/internal/utils/cose/key.d.ts +0 -4
- package/dist/internal/utils/cose/key.d.ts.map +0 -1
- package/dist/internal/utils/cose/key.js +0 -86
- package/dist/internal/utils/cose/key.js.map +0 -1
- package/dist/internal/utils/cose-sign-token.d.ts +0 -9
- package/dist/internal/utils/cose-sign-token.d.ts.map +0 -1
- package/dist/internal/utils/cose-sign-token.js +0 -12
- package/dist/internal/utils/cose-sign-token.js.map +0 -1
- package/dist/internal/utils/cose-signature.d.ts +0 -16
- package/dist/internal/utils/cose-signature.d.ts.map +0 -1
- package/dist/internal/utils/cose-signature.js +0 -17
- package/dist/internal/utils/cose-signature.js.map +0 -1
- package/dist/types/cose-target.d.ts +0 -2
- package/dist/types/cose-target.d.ts.map +0 -1
- package/dist/types/cose-target.js.map +0 -1
- package/dist/types/cwe/cwe-decode.d.ts +0 -18
- package/dist/types/cwe/cwe-decode.d.ts.map +0 -1
- package/dist/types/cwe/cwe-decode.js.map +0 -1
- package/dist/types/cwe/cwe-decrypt.d.ts +0 -15
- package/dist/types/cwe/cwe-decrypt.d.ts.map +0 -1
- package/dist/types/cwe/cwe-decrypt.js +0 -3
- package/dist/types/cwe/cwe-decrypt.js.map +0 -1
- package/dist/types/cwe/cwe-encrypt.d.ts +0 -12
- package/dist/types/cwe/cwe-encrypt.d.ts.map +0 -1
- package/dist/types/cwe/cwe-encrypt.js +0 -3
- package/dist/types/cwe/cwe-encrypt.js.map +0 -1
- package/dist/types/cwe/cwe-kit.d.ts +0 -9
- package/dist/types/cwe/cwe-kit.d.ts.map +0 -1
- package/dist/types/cwe/cwe-kit.js +0 -3
- package/dist/types/cwe/cwe-kit.js.map +0 -1
- package/dist/types/cwe/index.d.ts +0 -5
- package/dist/types/cwe/index.d.ts.map +0 -1
- package/dist/types/cwe/index.js.map +0 -1
- package/dist/types/cws/cws-decode.d.ts +0 -9
- package/dist/types/cws/cws-decode.d.ts.map +0 -1
- package/dist/types/cws/cws-decode.js +0 -3
- package/dist/types/cws/cws-decode.js.map +0 -1
- package/dist/types/cws/cws-kit.d.ts +0 -8
- package/dist/types/cws/cws-kit.d.ts.map +0 -1
- package/dist/types/cws/cws-kit.js +0 -3
- package/dist/types/cws/cws-kit.js.map +0 -1
- package/dist/types/cws/cws-parse.d.ts +0 -14
- package/dist/types/cws/cws-parse.d.ts.map +0 -1
- package/dist/types/cws/cws-parse.js +0 -3
- package/dist/types/cws/cws-parse.js.map +0 -1
- package/dist/types/cws/cws-sign.d.ts +0 -14
- package/dist/types/cws/cws-sign.d.ts.map +0 -1
- package/dist/types/cws/cws-sign.js +0 -3
- package/dist/types/cws/cws-sign.js.map +0 -1
- package/dist/types/cws/index.d.ts +0 -5
- package/dist/types/cws/index.d.ts.map +0 -1
- package/dist/types/cws/index.js.map +0 -1
- package/dist/types/cwt/cwt-claims.d.ts +0 -3
- package/dist/types/cwt/cwt-claims.d.ts.map +0 -1
- package/dist/types/cwt/cwt-claims.js +0 -3
- package/dist/types/cwt/cwt-claims.js.map +0 -1
- package/dist/types/cwt/cwt-decode.d.ts +0 -10
- package/dist/types/cwt/cwt-decode.d.ts.map +0 -1
- package/dist/types/cwt/cwt-decode.js +0 -3
- package/dist/types/cwt/cwt-decode.js.map +0 -1
- package/dist/types/cwt/cwt-kit.d.ts +0 -3
- package/dist/types/cwt/cwt-kit.d.ts.map +0 -1
- package/dist/types/cwt/cwt-kit.js +0 -3
- package/dist/types/cwt/cwt-kit.js.map +0 -1
- package/dist/types/cwt/cwt-parse.d.ts +0 -15
- package/dist/types/cwt/cwt-parse.d.ts.map +0 -1
- package/dist/types/cwt/cwt-parse.js +0 -3
- package/dist/types/cwt/cwt-parse.js.map +0 -1
- package/dist/types/cwt/cwt-sign.d.ts +0 -17
- package/dist/types/cwt/cwt-sign.d.ts.map +0 -1
- package/dist/types/cwt/cwt-sign.js +0 -3
- package/dist/types/cwt/cwt-sign.js.map +0 -1
- package/dist/types/cwt/cwt-validate.d.ts +0 -3
- package/dist/types/cwt/cwt-validate.d.ts.map +0 -1
- package/dist/types/cwt/cwt-validate.js +0 -3
- package/dist/types/cwt/cwt-validate.js.map +0 -1
- package/dist/types/cwt/cwt-verify.d.ts +0 -3
- package/dist/types/cwt/cwt-verify.d.ts.map +0 -1
- package/dist/types/cwt/cwt-verify.js +0 -3
- package/dist/types/cwt/cwt-verify.js.map +0 -1
- package/dist/types/cwt/index.d.ts +0 -8
- package/dist/types/cwt/index.d.ts.map +0 -1
- package/dist/types/cwt/index.js.map +0 -1
- package/dist/types/jwt/jwt-claims.d.ts +0 -38
- package/dist/types/jwt/jwt-claims.d.ts.map +0 -1
- package/dist/types/jwt/jwt-claims.js.map +0 -1
- /package/dist/types/{jwt → claims/jwt}/jwt-claims.js +0 -0
|
@@ -1,1127 +0,0 @@
|
|
|
1
|
-
import { KeyObject } from "crypto";
|
|
2
|
-
import { KryptosKit } from "@lindorm/kryptos";
|
|
3
|
-
import { createMockLogger } from "@lindorm/logger";
|
|
4
|
-
import { importJWK } from "jose";
|
|
5
|
-
import { Encoder } from "cbor-x";
|
|
6
|
-
import {
|
|
7
|
-
Sign1,
|
|
8
|
-
Algorithms,
|
|
9
|
-
Headers,
|
|
10
|
-
ProtectedHeaders,
|
|
11
|
-
UnprotectedHeaders,
|
|
12
|
-
} from "@auth0/cose";
|
|
13
|
-
import { encode as cborEncode } from "cbor";
|
|
14
|
-
import { CwsKit } from "../src/classes/CwsKit";
|
|
15
|
-
import { CweKit } from "../src/classes/CweKit";
|
|
16
|
-
import { CwtKit } from "../src/classes/CwtKit";
|
|
17
|
-
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// cbor-x encoder configured identically to @auth0/cose (Maps, not objects)
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
const cborEncoder = new Encoder({
|
|
23
|
-
tagUint8Array: false,
|
|
24
|
-
useRecords: false,
|
|
25
|
-
mapsAsObjects: false,
|
|
26
|
-
} as any);
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
// Shared constants
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
|
|
32
|
-
const PLAINTEXT = "hello aegis cose interop";
|
|
33
|
-
const ISSUER = "https://cose-interop.test.lindorm.io/";
|
|
34
|
-
const SUBJECT = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d";
|
|
35
|
-
const logger = createMockLogger();
|
|
36
|
-
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
|
-
// Key generation helpers
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
|
|
41
|
-
const createEcSigKey = () =>
|
|
42
|
-
KryptosKit.generate.sig.ec({ algorithm: "ES256", curve: "P-256" });
|
|
43
|
-
|
|
44
|
-
const createOkpSigKey = () =>
|
|
45
|
-
KryptosKit.generate.sig.okp({ algorithm: "EdDSA", curve: "Ed25519" });
|
|
46
|
-
|
|
47
|
-
const createRsaSigKey = () => KryptosKit.generate.sig.rsa({ algorithm: "RS256" });
|
|
48
|
-
|
|
49
|
-
const createOctDirKey = () =>
|
|
50
|
-
KryptosKit.generate.enc.oct({ algorithm: "dir", encryption: "A256GCM" });
|
|
51
|
-
|
|
52
|
-
const createOctKwKey = () => KryptosKit.generate.enc.oct({ algorithm: "A128KW" });
|
|
53
|
-
|
|
54
|
-
// ---------------------------------------------------------------------------
|
|
55
|
-
// Helper: export public-only JWK for jose/auth0 verification
|
|
56
|
-
// ---------------------------------------------------------------------------
|
|
57
|
-
|
|
58
|
-
const toPublicJwk = (jwk: Record<string, unknown>): Record<string, unknown> => {
|
|
59
|
-
const { d, dp, dq, p, q, qi, k, ...publicParts } = jwk as any;
|
|
60
|
-
return publicParts;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
// Helper: get jose KeyLike from kryptos (public key for verify, private for sign)
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
|
-
|
|
67
|
-
const getJoseKey = async (
|
|
68
|
-
kryptos: ReturnType<typeof createEcSigKey>,
|
|
69
|
-
mode: "public" | "private" = "public",
|
|
70
|
-
): Promise<CryptoKey | KeyObject> => {
|
|
71
|
-
const jwk = kryptos.export("jwk");
|
|
72
|
-
const keyJwk = mode === "public" ? toPublicJwk(jwk) : jwk;
|
|
73
|
-
return (await importJWK(keyJwk, jwk.alg)) as CryptoKey | KeyObject;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// ---------------------------------------------------------------------------
|
|
77
|
-
// COSE label constants (from RFC 9052 / aegis COSE_HEADER/COSE_CLAIMS)
|
|
78
|
-
// ---------------------------------------------------------------------------
|
|
79
|
-
|
|
80
|
-
const COSE_LABEL = {
|
|
81
|
-
ALG: 1,
|
|
82
|
-
CRIT: 2,
|
|
83
|
-
CTY: 3,
|
|
84
|
-
KID: 4,
|
|
85
|
-
IV: 5,
|
|
86
|
-
TYP: 16,
|
|
87
|
-
OID: 400,
|
|
88
|
-
} as const;
|
|
89
|
-
|
|
90
|
-
const COSE_CLAIM = {
|
|
91
|
-
ISS: 1,
|
|
92
|
-
SUB: 2,
|
|
93
|
-
AUD: 3,
|
|
94
|
-
EXP: 4,
|
|
95
|
-
NBF: 5,
|
|
96
|
-
IAT: 6,
|
|
97
|
-
JTI: 7, // cti in COSE, mapped to jti in aegis
|
|
98
|
-
} as const;
|
|
99
|
-
|
|
100
|
-
// Map from aegis algorithm string to COSE integer label
|
|
101
|
-
const COSE_ALG_LABEL: Record<string, number> = {
|
|
102
|
-
ES256: -7,
|
|
103
|
-
ES384: -35,
|
|
104
|
-
ES512: -36,
|
|
105
|
-
EdDSA: -8,
|
|
106
|
-
PS256: -37,
|
|
107
|
-
PS384: -38,
|
|
108
|
-
PS512: -39,
|
|
109
|
-
RS256: -257,
|
|
110
|
-
RS384: -258,
|
|
111
|
-
RS512: -259,
|
|
112
|
-
HS256: 5,
|
|
113
|
-
HS384: 6,
|
|
114
|
-
HS512: 7,
|
|
115
|
-
A128GCM: 1,
|
|
116
|
-
A192GCM: 2,
|
|
117
|
-
A256GCM: 3,
|
|
118
|
-
dir: -6,
|
|
119
|
-
A128KW: -3,
|
|
120
|
-
A192KW: -4,
|
|
121
|
-
A256KW: -5,
|
|
122
|
-
"ECDH-ES": -25,
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
// ===========================================================================
|
|
126
|
-
// CWS (COSE Sign1) structural compliance tests
|
|
127
|
-
// ===========================================================================
|
|
128
|
-
|
|
129
|
-
describe("COSE interop: CWS structural compliance", () => {
|
|
130
|
-
describe.each([
|
|
131
|
-
{ name: "EC / ES256", createKey: createEcSigKey, algLabel: -7 },
|
|
132
|
-
{ name: "OKP / EdDSA", createKey: createOkpSigKey, algLabel: -8 },
|
|
133
|
-
{ name: "RSA / RS256", createKey: createRsaSigKey, algLabel: -257 },
|
|
134
|
-
])("$name", ({ createKey, algLabel }) => {
|
|
135
|
-
test("aegis CWS token decodes as valid COSE Sign1 4-tuple", () => {
|
|
136
|
-
const kryptos = createKey();
|
|
137
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
138
|
-
|
|
139
|
-
const { buffer } = kit.sign(PLAINTEXT);
|
|
140
|
-
|
|
141
|
-
// Decode the raw CBOR with cbor-x (not the mock)
|
|
142
|
-
const decoded = cborEncoder.decode(buffer);
|
|
143
|
-
|
|
144
|
-
// Must be a 4-element array: [protectedCbor, unprotectedMap, payload, signature]
|
|
145
|
-
expect(Array.isArray(decoded)).toBe(true);
|
|
146
|
-
expect(decoded).toHaveLength(4);
|
|
147
|
-
|
|
148
|
-
const [protectedCbor, unprotectedMap, payloadCbor, signature] = decoded;
|
|
149
|
-
|
|
150
|
-
// protectedCbor must be a Uint8Array/Buffer (CBOR bstr)
|
|
151
|
-
expect(Buffer.isBuffer(protectedCbor) || protectedCbor instanceof Uint8Array).toBe(
|
|
152
|
-
true,
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
// unprotectedMap must be a Map (decoded with mapsAsObjects: false)
|
|
156
|
-
expect(unprotectedMap).toBeInstanceOf(Map);
|
|
157
|
-
|
|
158
|
-
// payloadCbor must be a Uint8Array/Buffer
|
|
159
|
-
expect(Buffer.isBuffer(payloadCbor) || payloadCbor instanceof Uint8Array).toBe(
|
|
160
|
-
true,
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
// signature must be a Uint8Array/Buffer
|
|
164
|
-
expect(Buffer.isBuffer(signature) || signature instanceof Uint8Array).toBe(true);
|
|
165
|
-
expect(signature.length).toBeGreaterThan(0);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
test("protected header has correct COSE label mappings", () => {
|
|
169
|
-
const kryptos = createKey();
|
|
170
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
171
|
-
|
|
172
|
-
const { buffer } = kit.sign(PLAINTEXT);
|
|
173
|
-
|
|
174
|
-
const decoded = cborEncoder.decode(buffer);
|
|
175
|
-
const [protectedCbor] = decoded;
|
|
176
|
-
|
|
177
|
-
// Decode the protected header bytes
|
|
178
|
-
const protectedMap: Map<number, unknown> = cborEncoder.decode(protectedCbor);
|
|
179
|
-
expect(protectedMap).toBeInstanceOf(Map);
|
|
180
|
-
|
|
181
|
-
// Label 1 = algorithm (must match the expected COSE algorithm label)
|
|
182
|
-
expect(protectedMap.get(COSE_LABEL.ALG)).toBe(algLabel);
|
|
183
|
-
|
|
184
|
-
// Label 3 = content type
|
|
185
|
-
expect(protectedMap.get(COSE_LABEL.CTY)).toBe("text/plain; charset=utf-8");
|
|
186
|
-
|
|
187
|
-
// Label 16 = type
|
|
188
|
-
expect(protectedMap.get(COSE_LABEL.TYP)).toBe(
|
|
189
|
-
"application/cose; cose-type=cose-sign",
|
|
190
|
-
);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
test("unprotected header contains kid and oid labels", () => {
|
|
194
|
-
const kryptos = createKey();
|
|
195
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
196
|
-
|
|
197
|
-
const { buffer, objectId } = kit.sign(PLAINTEXT, {
|
|
198
|
-
objectId: "test-object-id-123",
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
const decoded = cborEncoder.decode(buffer);
|
|
202
|
-
const [, unprotectedMap] = decoded;
|
|
203
|
-
|
|
204
|
-
expect(unprotectedMap).toBeInstanceOf(Map);
|
|
205
|
-
|
|
206
|
-
// Label 4 = kid (COSE KID is bstr, aegis encodes as Buffer)
|
|
207
|
-
const kidValue = unprotectedMap.get(COSE_LABEL.KID);
|
|
208
|
-
expect(kidValue).toBeDefined();
|
|
209
|
-
// The kid is a Buffer containing the kryptos.id string
|
|
210
|
-
const kidStr =
|
|
211
|
-
kidValue instanceof Uint8Array
|
|
212
|
-
? Buffer.from(kidValue).toString("utf8")
|
|
213
|
-
: kidValue;
|
|
214
|
-
expect(kidStr).toBe(kryptos.id);
|
|
215
|
-
|
|
216
|
-
// Label 400 = oid (Lindorm extension)
|
|
217
|
-
const oidValue = unprotectedMap.get(COSE_LABEL.OID);
|
|
218
|
-
expect(oidValue).toBeDefined();
|
|
219
|
-
const oidStr =
|
|
220
|
-
oidValue instanceof Uint8Array
|
|
221
|
-
? Buffer.from(oidValue).toString("utf8")
|
|
222
|
-
: oidValue;
|
|
223
|
-
expect(oidStr).toBe(objectId);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
test("signature is computed over RFC 9052 Sig_structure", () => {
|
|
227
|
-
const kryptos = createKey();
|
|
228
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
229
|
-
|
|
230
|
-
const { buffer } = kit.sign(PLAINTEXT);
|
|
231
|
-
|
|
232
|
-
const decoded = cborEncoder.decode(buffer);
|
|
233
|
-
const [protectedCbor, , payloadCbor, signature] = decoded;
|
|
234
|
-
|
|
235
|
-
// Reconstruct the Sig_structure that aegis should have signed:
|
|
236
|
-
// ["Signature1", protectedCbor, external_aad (empty), payload]
|
|
237
|
-
const sigStructure = cborEncoder.encode([
|
|
238
|
-
"Signature1",
|
|
239
|
-
protectedCbor,
|
|
240
|
-
new Uint8Array(0),
|
|
241
|
-
payloadCbor,
|
|
242
|
-
]);
|
|
243
|
-
|
|
244
|
-
// We can't verify the signature here without reimplementing crypto,
|
|
245
|
-
// but we verify the structure exists and the token round-trips through aegis
|
|
246
|
-
expect(sigStructure).toBeInstanceOf(Uint8Array);
|
|
247
|
-
expect(sigStructure.length).toBeGreaterThan(0);
|
|
248
|
-
|
|
249
|
-
// Verify aegis can round-trip its own token
|
|
250
|
-
const result = kit.verify(buffer);
|
|
251
|
-
expect(result.payload).toBe(PLAINTEXT);
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
// ===========================================================================
|
|
257
|
-
// CWS (COSE Sign1) interop: aegis <-> @auth0/cose
|
|
258
|
-
// ===========================================================================
|
|
259
|
-
|
|
260
|
-
describe("COSE interop: aegis CWS <-> @auth0/cose Sign1", () => {
|
|
261
|
-
describe.each([
|
|
262
|
-
{
|
|
263
|
-
name: "EC / ES256",
|
|
264
|
-
createKey: createEcSigKey,
|
|
265
|
-
auth0Alg: Algorithms.ES256,
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
name: "OKP / EdDSA",
|
|
269
|
-
createKey: createOkpSigKey,
|
|
270
|
-
auth0Alg: Algorithms.EdDSA,
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
name: "RSA / RS256",
|
|
274
|
-
createKey: createRsaSigKey,
|
|
275
|
-
auth0Alg: Algorithms.RS256,
|
|
276
|
-
},
|
|
277
|
-
])("$name", ({ createKey, auth0Alg }) => {
|
|
278
|
-
test("aegis sign -> @auth0/cose decode + verify", async () => {
|
|
279
|
-
const kryptos = createKey();
|
|
280
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
281
|
-
|
|
282
|
-
const { buffer } = kit.sign(PLAINTEXT);
|
|
283
|
-
|
|
284
|
-
// Decode using @auth0/cose
|
|
285
|
-
const sign1 = Sign1.decode(buffer);
|
|
286
|
-
|
|
287
|
-
// Verify protected header algorithm matches
|
|
288
|
-
expect(sign1.protectedHeaders.get(Headers.Algorithm)).toBe(auth0Alg);
|
|
289
|
-
|
|
290
|
-
// The payload field should be the CBOR-encoded payload bytes
|
|
291
|
-
expect(sign1.payload).toBeInstanceOf(Uint8Array);
|
|
292
|
-
expect(sign1.payload.length).toBeGreaterThan(0);
|
|
293
|
-
|
|
294
|
-
// Verify the signature using jose KeyLike
|
|
295
|
-
const publicKey = await getJoseKey(kryptos, "public");
|
|
296
|
-
await expect(sign1.verify(publicKey)).resolves.toBeUndefined();
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
test("@auth0/cose sign -> aegis verify", async () => {
|
|
300
|
-
const kryptos = createKey();
|
|
301
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
302
|
-
|
|
303
|
-
// Get jose private key for @auth0/cose signing
|
|
304
|
-
const privateKey = await getJoseKey(kryptos, "private");
|
|
305
|
-
|
|
306
|
-
// Build COSE protected and unprotected headers matching aegis format.
|
|
307
|
-
// We use ProtectedHeaders/UnprotectedHeaders with `as any` to include
|
|
308
|
-
// Lindorm-proprietary labels (16=typ, 400=oid) that aren't in @auth0/cose's enum.
|
|
309
|
-
const protectedHeaders = new ProtectedHeaders([
|
|
310
|
-
[Headers.Algorithm, auth0Alg],
|
|
311
|
-
[Headers.ContentType, "text/plain; charset=utf-8"],
|
|
312
|
-
[COSE_LABEL.TYP, "application/cose; cose-type=cose-sign"],
|
|
313
|
-
] as any);
|
|
314
|
-
|
|
315
|
-
const unprotectedHeaders = new UnprotectedHeaders([
|
|
316
|
-
[Headers.KeyID, Buffer.from(kryptos.id, "utf-8")],
|
|
317
|
-
[COSE_LABEL.OID, Buffer.from("test-oid", "utf-8")],
|
|
318
|
-
] as any);
|
|
319
|
-
|
|
320
|
-
// aegis expects payloadCbor = cbor.encode(payloadBuffer) as the Sign1 payload
|
|
321
|
-
// We need to CBOR-encode the payload buffer to match aegis's double-encoding
|
|
322
|
-
const payloadBuffer = Buffer.from(PLAINTEXT, "utf-8");
|
|
323
|
-
const payloadCbor = cborEncoder.encode(payloadBuffer);
|
|
324
|
-
|
|
325
|
-
const sign1 = await Sign1.sign(
|
|
326
|
-
protectedHeaders,
|
|
327
|
-
unprotectedHeaders,
|
|
328
|
-
payloadCbor,
|
|
329
|
-
privateKey,
|
|
330
|
-
);
|
|
331
|
-
|
|
332
|
-
// @auth0/cose Sign1.encode() produces tagged CBOR (tag 18).
|
|
333
|
-
// aegis expects untagged CBOR arrays. Extract the raw components
|
|
334
|
-
// via getContentForEncoding() and re-encode as an untagged array.
|
|
335
|
-
const components = sign1.getContentForEncoding();
|
|
336
|
-
const tokenBytes = cborEncode(components);
|
|
337
|
-
|
|
338
|
-
// Verify with aegis
|
|
339
|
-
const result = kit.verify(tokenBytes);
|
|
340
|
-
expect(result.payload).toBe(PLAINTEXT);
|
|
341
|
-
expect(result.header.algorithm).toBe(kryptos.algorithm);
|
|
342
|
-
expect(result.header.contentType).toBe("text/plain; charset=utf-8");
|
|
343
|
-
expect(result.header.headerType).toBe("application/cose; cose-type=cose-sign");
|
|
344
|
-
});
|
|
345
|
-
});
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
// ===========================================================================
|
|
349
|
-
// CWE (COSE Encrypt) structural compliance tests
|
|
350
|
-
// ===========================================================================
|
|
351
|
-
|
|
352
|
-
describe("COSE interop: CWE structural compliance", () => {
|
|
353
|
-
test("aegis CWE token decodes as valid 4-tuple", () => {
|
|
354
|
-
const kryptos = createOctDirKey();
|
|
355
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
356
|
-
|
|
357
|
-
const { buffer } = kit.encrypt(PLAINTEXT);
|
|
358
|
-
|
|
359
|
-
const decoded = cborEncoder.decode(buffer);
|
|
360
|
-
|
|
361
|
-
// Must be a 4-element array: [protectedCbor, unprotectedMap, ciphertext, recipients]
|
|
362
|
-
expect(Array.isArray(decoded)).toBe(true);
|
|
363
|
-
expect(decoded).toHaveLength(4);
|
|
364
|
-
|
|
365
|
-
const [protectedCbor, unprotectedMap, ciphertext, recipients] = decoded;
|
|
366
|
-
|
|
367
|
-
// protectedCbor must be bstr
|
|
368
|
-
expect(Buffer.isBuffer(protectedCbor) || protectedCbor instanceof Uint8Array).toBe(
|
|
369
|
-
true,
|
|
370
|
-
);
|
|
371
|
-
|
|
372
|
-
// unprotectedMap must be a Map
|
|
373
|
-
expect(unprotectedMap).toBeInstanceOf(Map);
|
|
374
|
-
|
|
375
|
-
// ciphertext must be bstr
|
|
376
|
-
expect(Buffer.isBuffer(ciphertext) || ciphertext instanceof Uint8Array).toBe(true);
|
|
377
|
-
expect(ciphertext.length).toBeGreaterThan(0);
|
|
378
|
-
|
|
379
|
-
// recipients must be an array
|
|
380
|
-
expect(Array.isArray(recipients)).toBe(true);
|
|
381
|
-
expect(recipients.length).toBeGreaterThanOrEqual(1);
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
test("protected header label 1 = content encryption algorithm (A256GCM -> 3)", () => {
|
|
385
|
-
const kryptos = createOctDirKey();
|
|
386
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
387
|
-
|
|
388
|
-
const { buffer } = kit.encrypt(PLAINTEXT);
|
|
389
|
-
|
|
390
|
-
const decoded = cborEncoder.decode(buffer);
|
|
391
|
-
const [protectedCbor] = decoded;
|
|
392
|
-
|
|
393
|
-
const protectedMap: Map<number, unknown> = cborEncoder.decode(protectedCbor);
|
|
394
|
-
expect(protectedMap).toBeInstanceOf(Map);
|
|
395
|
-
|
|
396
|
-
// RFC 9052: protected header alg = content encryption algorithm
|
|
397
|
-
// A256GCM = label 3
|
|
398
|
-
expect(protectedMap.get(COSE_LABEL.ALG)).toBe(COSE_ALG_LABEL["A256GCM"]);
|
|
399
|
-
|
|
400
|
-
// Also verify typ and cty
|
|
401
|
-
expect(protectedMap.get(COSE_LABEL.TYP)).toBe(
|
|
402
|
-
"application/cose; cose-type=cose-encrypt",
|
|
403
|
-
);
|
|
404
|
-
expect(protectedMap.get(COSE_LABEL.CTY)).toBe("text/plain");
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
test("recipient header label 1 = key management algorithm", () => {
|
|
408
|
-
const kryptos = createOctKwKey();
|
|
409
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
410
|
-
|
|
411
|
-
const { buffer } = kit.encrypt(PLAINTEXT);
|
|
412
|
-
|
|
413
|
-
const decoded = cborEncoder.decode(buffer);
|
|
414
|
-
const [, , , recipients] = decoded;
|
|
415
|
-
|
|
416
|
-
// First recipient is [protectedCbor, recipientHeaderMap, publicEncryptionKey]
|
|
417
|
-
const [recipient] = recipients;
|
|
418
|
-
expect(Array.isArray(recipient)).toBe(true);
|
|
419
|
-
expect(recipient.length).toBe(3);
|
|
420
|
-
|
|
421
|
-
const [, recipientHeaderMap] = recipient;
|
|
422
|
-
expect(recipientHeaderMap).toBeInstanceOf(Map);
|
|
423
|
-
|
|
424
|
-
// Recipient header label 1 = key management algorithm (A128KW = -3)
|
|
425
|
-
expect(recipientHeaderMap.get(COSE_LABEL.ALG)).toBe(COSE_ALG_LABEL["A128KW"]);
|
|
426
|
-
|
|
427
|
-
// Recipient header label 4 = kid
|
|
428
|
-
const kidValue = recipientHeaderMap.get(COSE_LABEL.KID);
|
|
429
|
-
expect(kidValue).toBeDefined();
|
|
430
|
-
const kidStr =
|
|
431
|
-
kidValue instanceof Uint8Array ? Buffer.from(kidValue).toString("utf8") : kidValue;
|
|
432
|
-
expect(kidStr).toBe(kryptos.id);
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
test("ciphertext contains content + auth tag (GCM)", () => {
|
|
436
|
-
const kryptos = createOctDirKey();
|
|
437
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
438
|
-
|
|
439
|
-
const { buffer } = kit.encrypt(PLAINTEXT);
|
|
440
|
-
|
|
441
|
-
const decoded = cborEncoder.decode(buffer);
|
|
442
|
-
const [, , ciphertext] = decoded;
|
|
443
|
-
|
|
444
|
-
// GCM auth tag is 16 bytes (128 bits), so ciphertext must be longer than 16 bytes
|
|
445
|
-
// (actual content + 16 byte tag)
|
|
446
|
-
expect(ciphertext.length).toBeGreaterThan(16);
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
test("unprotected header contains iv label", () => {
|
|
450
|
-
const kryptos = createOctDirKey();
|
|
451
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
452
|
-
|
|
453
|
-
const { buffer } = kit.encrypt(PLAINTEXT);
|
|
454
|
-
|
|
455
|
-
const decoded = cborEncoder.decode(buffer);
|
|
456
|
-
const [, unprotectedMap] = decoded;
|
|
457
|
-
|
|
458
|
-
// Label 5 = iv
|
|
459
|
-
const iv = unprotectedMap.get(COSE_LABEL.IV);
|
|
460
|
-
expect(iv).toBeDefined();
|
|
461
|
-
expect(iv instanceof Uint8Array || Buffer.isBuffer(iv)).toBe(true);
|
|
462
|
-
// GCM IV is 12 bytes
|
|
463
|
-
expect(iv.length).toBe(12);
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
test("CWE round-trip: encrypt then decrypt produces original plaintext", () => {
|
|
467
|
-
const kryptos = createOctDirKey();
|
|
468
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
469
|
-
|
|
470
|
-
const { token } = kit.encrypt(PLAINTEXT);
|
|
471
|
-
const result = kit.decrypt(token);
|
|
472
|
-
|
|
473
|
-
expect(result.payload).toBe(PLAINTEXT);
|
|
474
|
-
// In COSE format, the protected header alg = content encryption algorithm
|
|
475
|
-
// This is mapped to header.algorithm (not header.encryption)
|
|
476
|
-
expect(result.header.algorithm).toBe("A256GCM");
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
test("CWE with A128KW round-trips correctly", () => {
|
|
480
|
-
const kryptos = createOctKwKey();
|
|
481
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A128GCM" });
|
|
482
|
-
|
|
483
|
-
const { token } = kit.encrypt(PLAINTEXT);
|
|
484
|
-
const result = kit.decrypt(token);
|
|
485
|
-
|
|
486
|
-
expect(result.payload).toBe(PLAINTEXT);
|
|
487
|
-
// COSE: protected alg = content encryption (A128GCM), recipient alg = key management (A128KW)
|
|
488
|
-
// parseTokenHeader maps protected alg to header.algorithm
|
|
489
|
-
expect(result.header.algorithm).toBe("A128GCM");
|
|
490
|
-
});
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
// ===========================================================================
|
|
494
|
-
// CWT claim label compliance tests
|
|
495
|
-
// ===========================================================================
|
|
496
|
-
|
|
497
|
-
describe("COSE interop: CWT claim labels (RFC 8392)", () => {
|
|
498
|
-
test("CWT payload uses standard integer claim labels", () => {
|
|
499
|
-
const kryptos = createEcSigKey();
|
|
500
|
-
const kit = new CwtKit({
|
|
501
|
-
issuer: ISSUER,
|
|
502
|
-
logger,
|
|
503
|
-
kryptos,
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
const { buffer } = kit.sign({
|
|
507
|
-
expires: "1h",
|
|
508
|
-
subject: SUBJECT,
|
|
509
|
-
tokenType: "access_token",
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
// Decode the outer CBOR array
|
|
513
|
-
const decoded = cborEncoder.decode(buffer);
|
|
514
|
-
expect(Array.isArray(decoded)).toBe(true);
|
|
515
|
-
expect(decoded).toHaveLength(4);
|
|
516
|
-
|
|
517
|
-
const [, , payloadCbor] = decoded;
|
|
518
|
-
|
|
519
|
-
// Decode the payload CBOR map
|
|
520
|
-
const payloadMap: Map<number, unknown> = cborEncoder.decode(payloadCbor);
|
|
521
|
-
expect(payloadMap).toBeInstanceOf(Map);
|
|
522
|
-
|
|
523
|
-
// RFC 8392 claim labels:
|
|
524
|
-
// Label 1 = iss
|
|
525
|
-
const issValue = payloadMap.get(COSE_CLAIM.ISS);
|
|
526
|
-
expect(issValue).toBe(ISSUER);
|
|
527
|
-
|
|
528
|
-
// Label 2 = sub
|
|
529
|
-
const subValue = payloadMap.get(COSE_CLAIM.SUB);
|
|
530
|
-
expect(subValue).toBeDefined();
|
|
531
|
-
// sub is stored as bstr in aegis, decode it
|
|
532
|
-
const subStr =
|
|
533
|
-
subValue instanceof Uint8Array ? Buffer.from(subValue).toString("utf8") : subValue;
|
|
534
|
-
expect(subStr).toBe(SUBJECT);
|
|
535
|
-
|
|
536
|
-
// Label 4 = exp
|
|
537
|
-
const expValue = payloadMap.get(COSE_CLAIM.EXP);
|
|
538
|
-
expect(typeof expValue).toBe("number");
|
|
539
|
-
expect(expValue).toBeGreaterThan(0);
|
|
540
|
-
|
|
541
|
-
// Label 6 = iat
|
|
542
|
-
const iatValue = payloadMap.get(COSE_CLAIM.IAT);
|
|
543
|
-
expect(typeof iatValue).toBe("number");
|
|
544
|
-
expect(iatValue).toBeGreaterThan(0);
|
|
545
|
-
|
|
546
|
-
// Label 7 = jti (cti in COSE, mapped from jti)
|
|
547
|
-
const jtiValue = payloadMap.get(COSE_CLAIM.JTI);
|
|
548
|
-
expect(jtiValue).toBeDefined();
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
test("CWT protected header has correct algorithm label", () => {
|
|
552
|
-
const kryptos = createEcSigKey();
|
|
553
|
-
const kit = new CwtKit({
|
|
554
|
-
issuer: ISSUER,
|
|
555
|
-
logger,
|
|
556
|
-
kryptos,
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
const { buffer } = kit.sign({
|
|
560
|
-
expires: "1h",
|
|
561
|
-
subject: SUBJECT,
|
|
562
|
-
tokenType: "access_token",
|
|
563
|
-
});
|
|
564
|
-
|
|
565
|
-
const decoded = cborEncoder.decode(buffer);
|
|
566
|
-
const [protectedCbor] = decoded;
|
|
567
|
-
|
|
568
|
-
const protectedMap: Map<number, unknown> = cborEncoder.decode(protectedCbor);
|
|
569
|
-
expect(protectedMap).toBeInstanceOf(Map);
|
|
570
|
-
|
|
571
|
-
// Algorithm label 1 = ES256 = -7
|
|
572
|
-
expect(protectedMap.get(COSE_LABEL.ALG)).toBe(COSE_ALG_LABEL["ES256"]);
|
|
573
|
-
|
|
574
|
-
// Type label 16
|
|
575
|
-
expect(protectedMap.get(COSE_LABEL.TYP)).toBe("application/cwt");
|
|
576
|
-
|
|
577
|
-
// Content type label 3
|
|
578
|
-
expect(protectedMap.get(COSE_LABEL.CTY)).toBe("application/json");
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
test("CWT with OKP/EdDSA verifiable by @auth0/cose Sign1", async () => {
|
|
582
|
-
const kryptos = createOkpSigKey();
|
|
583
|
-
const kit = new CwtKit({
|
|
584
|
-
issuer: ISSUER,
|
|
585
|
-
logger,
|
|
586
|
-
kryptos,
|
|
587
|
-
});
|
|
588
|
-
|
|
589
|
-
const { buffer } = kit.sign({
|
|
590
|
-
expires: "1h",
|
|
591
|
-
subject: SUBJECT,
|
|
592
|
-
tokenType: "access_token",
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
// @auth0/cose should be able to decode and verify the CWT
|
|
596
|
-
// since CWT uses the same COSE_Sign1 structure as CWS
|
|
597
|
-
const sign1 = Sign1.decode(buffer);
|
|
598
|
-
|
|
599
|
-
expect(sign1.protectedHeaders.get(Headers.Algorithm)).toBe(Algorithms.EdDSA);
|
|
600
|
-
|
|
601
|
-
const publicKey = await getJoseKey(kryptos, "public");
|
|
602
|
-
await expect(sign1.verify(publicKey)).resolves.toBeUndefined();
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
test("CWT with EC/ES256 verifiable by @auth0/cose Sign1", async () => {
|
|
606
|
-
const kryptos = createEcSigKey();
|
|
607
|
-
const kit = new CwtKit({
|
|
608
|
-
issuer: ISSUER,
|
|
609
|
-
logger,
|
|
610
|
-
kryptos,
|
|
611
|
-
});
|
|
612
|
-
|
|
613
|
-
const { buffer } = kit.sign({
|
|
614
|
-
expires: "1h",
|
|
615
|
-
subject: SUBJECT,
|
|
616
|
-
tokenType: "access_token",
|
|
617
|
-
});
|
|
618
|
-
|
|
619
|
-
const sign1 = Sign1.decode(buffer);
|
|
620
|
-
expect(sign1.protectedHeaders.get(Headers.Algorithm)).toBe(Algorithms.ES256);
|
|
621
|
-
|
|
622
|
-
const publicKey = await getJoseKey(kryptos, "public");
|
|
623
|
-
await expect(sign1.verify(publicKey)).resolves.toBeUndefined();
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
test("CWT with RSA/RS256 verifiable by @auth0/cose Sign1", async () => {
|
|
627
|
-
const kryptos = createRsaSigKey();
|
|
628
|
-
const kit = new CwtKit({
|
|
629
|
-
issuer: ISSUER,
|
|
630
|
-
logger,
|
|
631
|
-
kryptos,
|
|
632
|
-
});
|
|
633
|
-
|
|
634
|
-
const { buffer } = kit.sign({
|
|
635
|
-
expires: "1h",
|
|
636
|
-
subject: SUBJECT,
|
|
637
|
-
tokenType: "access_token",
|
|
638
|
-
});
|
|
639
|
-
|
|
640
|
-
const sign1 = Sign1.decode(buffer);
|
|
641
|
-
expect(sign1.protectedHeaders.get(Headers.Algorithm)).toBe(Algorithms.RS256);
|
|
642
|
-
|
|
643
|
-
const publicKey = await getJoseKey(kryptos, "public");
|
|
644
|
-
await expect(sign1.verify(publicKey)).resolves.toBeUndefined();
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
test("CWT round-trip through aegis sign + verify", () => {
|
|
648
|
-
const kryptos = createEcSigKey();
|
|
649
|
-
const kit = new CwtKit({
|
|
650
|
-
issuer: ISSUER,
|
|
651
|
-
logger,
|
|
652
|
-
kryptos,
|
|
653
|
-
});
|
|
654
|
-
|
|
655
|
-
const { token } = kit.sign({
|
|
656
|
-
expires: "1h",
|
|
657
|
-
subject: SUBJECT,
|
|
658
|
-
tokenType: "access_token",
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
const result = kit.verify(token);
|
|
662
|
-
expect(result.payload.issuer).toBe(ISSUER);
|
|
663
|
-
expect(result.payload.subject).toBe(SUBJECT);
|
|
664
|
-
expect(result.payload.tokenType).toBe("access_token");
|
|
665
|
-
expect(result.payload.expiresAt).toBeInstanceOf(Date);
|
|
666
|
-
});
|
|
667
|
-
});
|
|
668
|
-
|
|
669
|
-
// ===========================================================================
|
|
670
|
-
// Algorithm label mapping completeness
|
|
671
|
-
// ===========================================================================
|
|
672
|
-
|
|
673
|
-
describe("COSE interop: algorithm label mappings match RFC 9053", () => {
|
|
674
|
-
test.each([
|
|
675
|
-
{ alg: "ES256", label: -7 },
|
|
676
|
-
{ alg: "ES384", label: -35 },
|
|
677
|
-
{ alg: "ES512", label: -36 },
|
|
678
|
-
{ alg: "EdDSA", label: -8 },
|
|
679
|
-
{ alg: "RS256", label: -257 },
|
|
680
|
-
{ alg: "RS384", label: -258 },
|
|
681
|
-
{ alg: "RS512", label: -259 },
|
|
682
|
-
{ alg: "PS256", label: -37 },
|
|
683
|
-
{ alg: "PS384", label: -38 },
|
|
684
|
-
{ alg: "PS512", label: -39 },
|
|
685
|
-
{ alg: "HS256", label: 5 },
|
|
686
|
-
{ alg: "HS384", label: 6 },
|
|
687
|
-
{ alg: "HS512", label: 7 },
|
|
688
|
-
{ alg: "A128GCM", label: 1 },
|
|
689
|
-
{ alg: "A192GCM", label: 2 },
|
|
690
|
-
{ alg: "A256GCM", label: 3 },
|
|
691
|
-
])("aegis maps $alg to COSE label $label", ({ alg, label }) => {
|
|
692
|
-
expect(COSE_ALG_LABEL[alg]).toBe(label);
|
|
693
|
-
});
|
|
694
|
-
|
|
695
|
-
// Verify aegis signature algorithms match @auth0/cose enum values
|
|
696
|
-
test.each([
|
|
697
|
-
{ alg: "EdDSA", auth0Value: Algorithms.EdDSA },
|
|
698
|
-
{ alg: "ES256", auth0Value: Algorithms.ES256 },
|
|
699
|
-
{ alg: "ES384", auth0Value: Algorithms.ES384 },
|
|
700
|
-
{ alg: "ES512", auth0Value: Algorithms.ES512 },
|
|
701
|
-
{ alg: "RS256", auth0Value: Algorithms.RS256 },
|
|
702
|
-
{ alg: "RS384", auth0Value: Algorithms.RS384 },
|
|
703
|
-
{ alg: "RS512", auth0Value: Algorithms.RS512 },
|
|
704
|
-
{ alg: "PS256", auth0Value: Algorithms.PS256 },
|
|
705
|
-
{ alg: "PS384", auth0Value: Algorithms.PS384 },
|
|
706
|
-
{ alg: "PS512", auth0Value: Algorithms.PS512 },
|
|
707
|
-
])("aegis $alg label matches @auth0/cose Algorithms.$alg", ({ alg, auth0Value }) => {
|
|
708
|
-
expect(COSE_ALG_LABEL[alg]).toBe(auth0Value);
|
|
709
|
-
});
|
|
710
|
-
});
|
|
711
|
-
|
|
712
|
-
// ===========================================================================
|
|
713
|
-
// COSE header label mappings match RFC 9052
|
|
714
|
-
// ===========================================================================
|
|
715
|
-
|
|
716
|
-
describe("COSE interop: header label mappings match RFC 9052", () => {
|
|
717
|
-
test.each([
|
|
718
|
-
{ header: "Algorithm", aegisLabel: COSE_LABEL.ALG, auth0Value: Headers.Algorithm },
|
|
719
|
-
{ header: "Critical", aegisLabel: COSE_LABEL.CRIT, auth0Value: Headers.Critical },
|
|
720
|
-
{
|
|
721
|
-
header: "ContentType",
|
|
722
|
-
aegisLabel: COSE_LABEL.CTY,
|
|
723
|
-
auth0Value: Headers.ContentType,
|
|
724
|
-
},
|
|
725
|
-
{ header: "KeyID", aegisLabel: COSE_LABEL.KID, auth0Value: Headers.KeyID },
|
|
726
|
-
{ header: "IV", aegisLabel: COSE_LABEL.IV, auth0Value: Headers.IV },
|
|
727
|
-
])(
|
|
728
|
-
"aegis label for $header matches @auth0/cose Headers.$header",
|
|
729
|
-
({ aegisLabel, auth0Value }) => {
|
|
730
|
-
expect(aegisLabel).toBe(auth0Value);
|
|
731
|
-
},
|
|
732
|
-
);
|
|
733
|
-
});
|
|
734
|
-
|
|
735
|
-
// ===========================================================================
|
|
736
|
-
// External target mode: proprietary labels as string keys
|
|
737
|
-
// ===========================================================================
|
|
738
|
-
|
|
739
|
-
describe("COSE interop: external target mode", () => {
|
|
740
|
-
describe("CWS with target: external", () => {
|
|
741
|
-
test("no integer labels >= 400 in unprotected header", () => {
|
|
742
|
-
const kryptos = createEcSigKey();
|
|
743
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
744
|
-
|
|
745
|
-
const { buffer } = kit.sign(PLAINTEXT, {
|
|
746
|
-
objectId: "ext-test-oid",
|
|
747
|
-
target: "external",
|
|
748
|
-
});
|
|
749
|
-
|
|
750
|
-
const decoded = cborEncoder.decode(buffer);
|
|
751
|
-
const [, unprotectedMap] = decoded;
|
|
752
|
-
|
|
753
|
-
expect(unprotectedMap).toBeInstanceOf(Map);
|
|
754
|
-
|
|
755
|
-
// No integer keys >= 400 should exist
|
|
756
|
-
for (const key of unprotectedMap.keys()) {
|
|
757
|
-
if (typeof key === "number") {
|
|
758
|
-
expect(key).toBeLessThan(400);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// oid should be present as string key with raw value (not bstr)
|
|
763
|
-
expect(unprotectedMap.get("oid")).toBe("ext-test-oid");
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
test("standard RFC labels still use integers", () => {
|
|
767
|
-
const kryptos = createEcSigKey();
|
|
768
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
769
|
-
|
|
770
|
-
const { buffer } = kit.sign(PLAINTEXT, { target: "external" });
|
|
771
|
-
|
|
772
|
-
const decoded = cborEncoder.decode(buffer);
|
|
773
|
-
const [protectedCbor, unprotectedMap] = decoded;
|
|
774
|
-
|
|
775
|
-
// Protected header still has integer labels
|
|
776
|
-
const protectedMap: Map<number, unknown> = cborEncoder.decode(protectedCbor);
|
|
777
|
-
expect(protectedMap.get(COSE_LABEL.ALG)).toBe(COSE_ALG_LABEL["ES256"]);
|
|
778
|
-
expect(protectedMap.get(COSE_LABEL.CTY)).toBe("text/plain; charset=utf-8");
|
|
779
|
-
expect(protectedMap.get(COSE_LABEL.TYP)).toBe(
|
|
780
|
-
"application/cose; cose-type=cose-sign",
|
|
781
|
-
);
|
|
782
|
-
|
|
783
|
-
// Unprotected header: kid still uses integer label 4
|
|
784
|
-
const kidValue = unprotectedMap.get(COSE_LABEL.KID);
|
|
785
|
-
expect(kidValue).toBeDefined();
|
|
786
|
-
});
|
|
787
|
-
|
|
788
|
-
test("aegis sign (external) -> @auth0/cose decode + verify", async () => {
|
|
789
|
-
const kryptos = createEcSigKey();
|
|
790
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
791
|
-
|
|
792
|
-
const { buffer } = kit.sign(PLAINTEXT, { target: "external" });
|
|
793
|
-
|
|
794
|
-
const sign1 = Sign1.decode(buffer);
|
|
795
|
-
expect(sign1.protectedHeaders.get(Headers.Algorithm)).toBe(Algorithms.ES256);
|
|
796
|
-
|
|
797
|
-
const publicKey = await getJoseKey(kryptos, "public");
|
|
798
|
-
await expect(sign1.verify(publicKey)).resolves.toBeUndefined();
|
|
799
|
-
});
|
|
800
|
-
|
|
801
|
-
test("round-trip: external CWS sign -> aegis verify", () => {
|
|
802
|
-
const kryptos = createEcSigKey();
|
|
803
|
-
const kit = new CwsKit({ logger, kryptos });
|
|
804
|
-
|
|
805
|
-
const { buffer } = kit.sign(PLAINTEXT, {
|
|
806
|
-
objectId: "roundtrip-ext",
|
|
807
|
-
target: "external",
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
// Decode path handles both formats
|
|
811
|
-
const result = kit.verify(buffer);
|
|
812
|
-
expect(result.payload).toBe(PLAINTEXT);
|
|
813
|
-
expect(result.header.objectId).toBe("roundtrip-ext");
|
|
814
|
-
});
|
|
815
|
-
});
|
|
816
|
-
|
|
817
|
-
describe("CWE with target: external", () => {
|
|
818
|
-
test("no integer labels >= 400 in unprotected header", () => {
|
|
819
|
-
const kryptos = createOctDirKey();
|
|
820
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
821
|
-
|
|
822
|
-
const { buffer } = kit.encrypt(PLAINTEXT, {
|
|
823
|
-
objectId: "cwe-ext-oid",
|
|
824
|
-
target: "external",
|
|
825
|
-
});
|
|
826
|
-
|
|
827
|
-
const decoded = cborEncoder.decode(buffer);
|
|
828
|
-
const [, unprotectedMap] = decoded;
|
|
829
|
-
|
|
830
|
-
expect(unprotectedMap).toBeInstanceOf(Map);
|
|
831
|
-
|
|
832
|
-
for (const key of unprotectedMap.keys()) {
|
|
833
|
-
if (typeof key === "number") {
|
|
834
|
-
expect(key).toBeLessThan(400);
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
// oid present as string key
|
|
839
|
-
expect(unprotectedMap.get("oid")).toBe("cwe-ext-oid");
|
|
840
|
-
});
|
|
841
|
-
|
|
842
|
-
test("round-trip: external CWE encrypt -> decrypt", () => {
|
|
843
|
-
const kryptos = createOctDirKey();
|
|
844
|
-
const kit = new CweKit({ logger, kryptos, encryption: "A256GCM" });
|
|
845
|
-
|
|
846
|
-
const { token } = kit.encrypt(PLAINTEXT, {
|
|
847
|
-
objectId: "cwe-ext-rt",
|
|
848
|
-
target: "external",
|
|
849
|
-
});
|
|
850
|
-
|
|
851
|
-
const result = kit.decrypt(token);
|
|
852
|
-
expect(result.payload).toBe(PLAINTEXT);
|
|
853
|
-
});
|
|
854
|
-
});
|
|
855
|
-
|
|
856
|
-
describe("CWT with target: external", () => {
|
|
857
|
-
test("no integer labels >= 400 in payload or headers", () => {
|
|
858
|
-
const kryptos = createEcSigKey();
|
|
859
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
860
|
-
|
|
861
|
-
const { buffer } = kit.sign(
|
|
862
|
-
{
|
|
863
|
-
expires: "1h",
|
|
864
|
-
subject: SUBJECT,
|
|
865
|
-
tokenType: "access_token",
|
|
866
|
-
},
|
|
867
|
-
{ target: "external" },
|
|
868
|
-
);
|
|
869
|
-
|
|
870
|
-
const decoded = cborEncoder.decode(buffer);
|
|
871
|
-
const [, unprotectedMap, payloadCbor] = decoded;
|
|
872
|
-
|
|
873
|
-
// Unprotected header: no integer keys >= 400
|
|
874
|
-
expect(unprotectedMap).toBeInstanceOf(Map);
|
|
875
|
-
for (const key of unprotectedMap.keys()) {
|
|
876
|
-
if (typeof key === "number") {
|
|
877
|
-
expect(key).toBeLessThan(400);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
// Payload: no integer keys >= 400
|
|
882
|
-
const payloadMap: Map<number | string, unknown> = cborEncoder.decode(payloadCbor);
|
|
883
|
-
expect(payloadMap).toBeInstanceOf(Map);
|
|
884
|
-
for (const key of payloadMap.keys()) {
|
|
885
|
-
if (typeof key === "number") {
|
|
886
|
-
expect(key).toBeLessThan(400);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
// Proprietary claims present as string keys
|
|
891
|
-
expect(payloadMap.get("token_type")).toBe("access_token");
|
|
892
|
-
});
|
|
893
|
-
|
|
894
|
-
test("standard CWT claims still use integer labels", () => {
|
|
895
|
-
const kryptos = createEcSigKey();
|
|
896
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
897
|
-
|
|
898
|
-
const { buffer } = kit.sign(
|
|
899
|
-
{
|
|
900
|
-
expires: "1h",
|
|
901
|
-
subject: SUBJECT,
|
|
902
|
-
tokenType: "access_token",
|
|
903
|
-
},
|
|
904
|
-
{ target: "external" },
|
|
905
|
-
);
|
|
906
|
-
|
|
907
|
-
const decoded = cborEncoder.decode(buffer);
|
|
908
|
-
const [protectedCbor, , payloadCbor] = decoded;
|
|
909
|
-
|
|
910
|
-
// Protected header: standard labels
|
|
911
|
-
const protectedMap: Map<number, unknown> = cborEncoder.decode(protectedCbor);
|
|
912
|
-
expect(protectedMap.get(COSE_LABEL.ALG)).toBe(COSE_ALG_LABEL["ES256"]);
|
|
913
|
-
expect(protectedMap.get(COSE_LABEL.TYP)).toBe("application/cwt");
|
|
914
|
-
|
|
915
|
-
// Payload: standard claims use integer labels
|
|
916
|
-
const payloadMap: Map<number | string, unknown> = cborEncoder.decode(payloadCbor);
|
|
917
|
-
expect(payloadMap.get(COSE_CLAIM.ISS)).toBe(ISSUER);
|
|
918
|
-
expect(typeof payloadMap.get(COSE_CLAIM.EXP)).toBe("number");
|
|
919
|
-
expect(typeof payloadMap.get(COSE_CLAIM.IAT)).toBe("number");
|
|
920
|
-
});
|
|
921
|
-
|
|
922
|
-
test("aegis CWT (external) verifiable by @auth0/cose Sign1", async () => {
|
|
923
|
-
const kryptos = createEcSigKey();
|
|
924
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
925
|
-
|
|
926
|
-
const { buffer } = kit.sign(
|
|
927
|
-
{
|
|
928
|
-
expires: "1h",
|
|
929
|
-
subject: SUBJECT,
|
|
930
|
-
tokenType: "access_token",
|
|
931
|
-
},
|
|
932
|
-
{ target: "external" },
|
|
933
|
-
);
|
|
934
|
-
|
|
935
|
-
const sign1 = Sign1.decode(buffer);
|
|
936
|
-
expect(sign1.protectedHeaders.get(Headers.Algorithm)).toBe(Algorithms.ES256);
|
|
937
|
-
|
|
938
|
-
const publicKey = await getJoseKey(kryptos, "public");
|
|
939
|
-
await expect(sign1.verify(publicKey)).resolves.toBeUndefined();
|
|
940
|
-
});
|
|
941
|
-
|
|
942
|
-
test("round-trip: external CWT sign -> aegis verify", () => {
|
|
943
|
-
const kryptos = createEcSigKey();
|
|
944
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
945
|
-
|
|
946
|
-
const { token } = kit.sign(
|
|
947
|
-
{
|
|
948
|
-
expires: "1h",
|
|
949
|
-
subject: SUBJECT,
|
|
950
|
-
tokenType: "access_token",
|
|
951
|
-
},
|
|
952
|
-
{ target: "external" },
|
|
953
|
-
);
|
|
954
|
-
|
|
955
|
-
const result = kit.verify(token);
|
|
956
|
-
expect(result.payload.issuer).toBe(ISSUER);
|
|
957
|
-
expect(result.payload.subject).toBe(SUBJECT);
|
|
958
|
-
expect(result.payload.tokenType).toBe("access_token");
|
|
959
|
-
});
|
|
960
|
-
|
|
961
|
-
test("decode of external token produces same parsed output as internal", () => {
|
|
962
|
-
const kryptos = createEcSigKey();
|
|
963
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
964
|
-
|
|
965
|
-
const content = {
|
|
966
|
-
expires: "1h",
|
|
967
|
-
subject: SUBJECT,
|
|
968
|
-
tokenType: "access_token",
|
|
969
|
-
} as const;
|
|
970
|
-
|
|
971
|
-
const internal = kit.sign(content);
|
|
972
|
-
const external = kit.sign(content, { target: "external" });
|
|
973
|
-
|
|
974
|
-
const parsedInternal = CwtKit.parse(internal.token);
|
|
975
|
-
const parsedExternal = CwtKit.parse(external.token);
|
|
976
|
-
|
|
977
|
-
// Same parsed payload fields
|
|
978
|
-
expect(parsedExternal.payload.issuer).toBe(parsedInternal.payload.issuer);
|
|
979
|
-
expect(parsedExternal.payload.subject).toBe(parsedInternal.payload.subject);
|
|
980
|
-
expect(parsedExternal.payload.tokenType).toBe(parsedInternal.payload.tokenType);
|
|
981
|
-
expect(parsedExternal.header.algorithm).toBe(parsedInternal.header.algorithm);
|
|
982
|
-
expect(parsedExternal.header.headerType).toBe(parsedInternal.header.headerType);
|
|
983
|
-
});
|
|
984
|
-
});
|
|
985
|
-
});
|
|
986
|
-
|
|
987
|
-
// ===========================================================================
|
|
988
|
-
// Custom COSE claim labels (>= 900) for CWT payloads
|
|
989
|
-
// ===========================================================================
|
|
990
|
-
|
|
991
|
-
describe("COSE interop: custom claim labels (>= 900)", () => {
|
|
992
|
-
test("CWT with custom claims produces integer labels in CBOR payload", () => {
|
|
993
|
-
const kryptos = createEcSigKey();
|
|
994
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
995
|
-
|
|
996
|
-
const { buffer } = kit.sign({
|
|
997
|
-
expires: "1h",
|
|
998
|
-
subject: SUBJECT,
|
|
999
|
-
tokenType: "access_token",
|
|
1000
|
-
claims: { 900: "user-abc", 901: 42 },
|
|
1001
|
-
});
|
|
1002
|
-
|
|
1003
|
-
const decoded = cborEncoder.decode(buffer);
|
|
1004
|
-
const [, , payloadCbor] = decoded;
|
|
1005
|
-
|
|
1006
|
-
const payloadMap: Map<number | string, unknown> = cborEncoder.decode(payloadCbor);
|
|
1007
|
-
expect(payloadMap).toBeInstanceOf(Map);
|
|
1008
|
-
|
|
1009
|
-
// Custom claims use integer keys
|
|
1010
|
-
expect(payloadMap.get(900)).toBe("user-abc");
|
|
1011
|
-
expect(payloadMap.get(901)).toBe(42);
|
|
1012
|
-
|
|
1013
|
-
// Standard claims still present
|
|
1014
|
-
expect(payloadMap.get(COSE_CLAIM.ISS)).toBe(ISSUER);
|
|
1015
|
-
});
|
|
1016
|
-
|
|
1017
|
-
test("CWT with custom claims verifiable by @auth0/cose Sign1", async () => {
|
|
1018
|
-
const kryptos = createEcSigKey();
|
|
1019
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
1020
|
-
|
|
1021
|
-
const { buffer } = kit.sign({
|
|
1022
|
-
expires: "1h",
|
|
1023
|
-
subject: SUBJECT,
|
|
1024
|
-
tokenType: "access_token",
|
|
1025
|
-
claims: { 900: "user-abc", 901: 42 },
|
|
1026
|
-
});
|
|
1027
|
-
|
|
1028
|
-
const sign1 = Sign1.decode(buffer);
|
|
1029
|
-
expect(sign1.protectedHeaders.get(Headers.Algorithm)).toBe(Algorithms.ES256);
|
|
1030
|
-
|
|
1031
|
-
const publicKey = await getJoseKey(kryptos, "public");
|
|
1032
|
-
await expect(sign1.verify(publicKey)).resolves.toBeUndefined();
|
|
1033
|
-
});
|
|
1034
|
-
|
|
1035
|
-
test("round-trip sign -> verify preserves custom claims", () => {
|
|
1036
|
-
const kryptos = createEcSigKey();
|
|
1037
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
1038
|
-
|
|
1039
|
-
const { token } = kit.sign({
|
|
1040
|
-
expires: "1h",
|
|
1041
|
-
subject: SUBJECT,
|
|
1042
|
-
tokenType: "access_token",
|
|
1043
|
-
claims: { 900: "user-abc", 901: 42 },
|
|
1044
|
-
});
|
|
1045
|
-
|
|
1046
|
-
const result = kit.verify(token);
|
|
1047
|
-
expect(result.payload.claims["900"]).toBe("user-abc");
|
|
1048
|
-
expect(result.payload.claims["901"]).toBe(42);
|
|
1049
|
-
expect(result.payload.issuer).toBe(ISSUER);
|
|
1050
|
-
});
|
|
1051
|
-
|
|
1052
|
-
test("external target: custom claims use string keys, no integer labels >= 900", () => {
|
|
1053
|
-
const kryptos = createEcSigKey();
|
|
1054
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
1055
|
-
|
|
1056
|
-
const { buffer } = kit.sign(
|
|
1057
|
-
{
|
|
1058
|
-
expires: "1h",
|
|
1059
|
-
subject: SUBJECT,
|
|
1060
|
-
tokenType: "access_token",
|
|
1061
|
-
claims: { 900: "user-abc" },
|
|
1062
|
-
},
|
|
1063
|
-
{ target: "external" },
|
|
1064
|
-
);
|
|
1065
|
-
|
|
1066
|
-
const decoded = cborEncoder.decode(buffer);
|
|
1067
|
-
const [, , payloadCbor] = decoded;
|
|
1068
|
-
|
|
1069
|
-
const payloadMap: Map<number | string, unknown> = cborEncoder.decode(payloadCbor);
|
|
1070
|
-
expect(payloadMap).toBeInstanceOf(Map);
|
|
1071
|
-
|
|
1072
|
-
// No integer keys >= 900
|
|
1073
|
-
for (const key of payloadMap.keys()) {
|
|
1074
|
-
if (typeof key === "number") {
|
|
1075
|
-
expect(key).toBeLessThan(900);
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
// Custom claim present as string key
|
|
1080
|
-
expect(payloadMap.get("900")).toBe("user-abc");
|
|
1081
|
-
});
|
|
1082
|
-
|
|
1083
|
-
test("large custom labels (e.g. 10000) work correctly", () => {
|
|
1084
|
-
const kryptos = createEcSigKey();
|
|
1085
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
1086
|
-
|
|
1087
|
-
const { buffer, token } = kit.sign({
|
|
1088
|
-
expires: "1h",
|
|
1089
|
-
subject: SUBJECT,
|
|
1090
|
-
tokenType: "access_token",
|
|
1091
|
-
claims: { 10000: "large-label" },
|
|
1092
|
-
});
|
|
1093
|
-
|
|
1094
|
-
const decoded = cborEncoder.decode(buffer);
|
|
1095
|
-
const [, , payloadCbor] = decoded;
|
|
1096
|
-
const payloadMap: Map<number | string, unknown> = cborEncoder.decode(payloadCbor);
|
|
1097
|
-
expect(payloadMap.get(10000)).toBe("large-label");
|
|
1098
|
-
|
|
1099
|
-
const result = kit.verify(token);
|
|
1100
|
-
expect(result.payload.claims["10000"]).toBe("large-label");
|
|
1101
|
-
});
|
|
1102
|
-
|
|
1103
|
-
test("token with integer custom claims is smaller than string key equivalent", () => {
|
|
1104
|
-
const kryptos = createEcSigKey();
|
|
1105
|
-
const kit = new CwtKit({ issuer: ISSUER, logger, kryptos });
|
|
1106
|
-
|
|
1107
|
-
const internalResult = kit.sign({
|
|
1108
|
-
expires: "1h",
|
|
1109
|
-
subject: SUBJECT,
|
|
1110
|
-
tokenType: "access_token",
|
|
1111
|
-
claims: { 900: "user-abc", 901: 42 },
|
|
1112
|
-
});
|
|
1113
|
-
|
|
1114
|
-
const externalResult = kit.sign(
|
|
1115
|
-
{
|
|
1116
|
-
expires: "1h",
|
|
1117
|
-
subject: SUBJECT,
|
|
1118
|
-
tokenType: "access_token",
|
|
1119
|
-
claims: { 900: "user-abc", 901: 42 },
|
|
1120
|
-
},
|
|
1121
|
-
{ target: "external" },
|
|
1122
|
-
);
|
|
1123
|
-
|
|
1124
|
-
// Internal (integer labels) should be smaller than external (string keys)
|
|
1125
|
-
expect(internalResult.buffer.length).toBeLessThan(externalResult.buffer.length);
|
|
1126
|
-
});
|
|
1127
|
-
});
|