@opentdf/sdk 0.1.0-beta.1701
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/README.md +52 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/src/access.js +155 -0
- package/dist/cjs/src/auth/Eas.js +60 -0
- package/dist/cjs/src/auth/auth.js +79 -0
- package/dist/cjs/src/auth/oidc-clientcredentials-provider.js +26 -0
- package/dist/cjs/src/auth/oidc-externaljwt-provider.js +33 -0
- package/dist/cjs/src/auth/oidc-refreshtoken-provider.js +34 -0
- package/dist/cjs/src/auth/oidc.js +222 -0
- package/dist/cjs/src/auth/providers.js +143 -0
- package/dist/cjs/src/encodings/base64.js +154 -0
- package/dist/cjs/src/encodings/hex.js +70 -0
- package/dist/cjs/src/encodings/index.js +29 -0
- package/dist/cjs/src/errors.js +138 -0
- package/dist/cjs/src/index.js +344 -0
- package/dist/cjs/src/nanotdf/Client.js +296 -0
- package/dist/cjs/src/nanotdf/NanoTDF.js +94 -0
- package/dist/cjs/src/nanotdf/browser-entry.js +19 -0
- package/dist/cjs/src/nanotdf/constants.js +5 -0
- package/dist/cjs/src/nanotdf/decrypt.js +17 -0
- package/dist/cjs/src/nanotdf/encrypt-dataset.js +38 -0
- package/dist/cjs/src/nanotdf/encrypt.js +132 -0
- package/dist/cjs/src/nanotdf/enum/CipherEnum.js +13 -0
- package/dist/cjs/src/nanotdf/enum/CurveNameEnum.js +15 -0
- package/dist/cjs/src/nanotdf/enum/EncodingEnum.js +8 -0
- package/dist/cjs/src/nanotdf/enum/PolicyTypeEnum.js +11 -0
- package/dist/cjs/src/nanotdf/enum/ProtocolEnum.js +10 -0
- package/dist/cjs/src/nanotdf/enum/ResourceLocatorIdentifierEnum.js +11 -0
- package/dist/cjs/src/nanotdf/helpers/calculateByCurve.js +29 -0
- package/dist/cjs/src/nanotdf/helpers/getHkdfSalt.js +11 -0
- package/dist/cjs/src/nanotdf/index.js +25 -0
- package/dist/cjs/src/nanotdf/interfaces/PolicyInterface.js +3 -0
- package/dist/cjs/src/nanotdf/models/Ciphers.js +61 -0
- package/dist/cjs/src/nanotdf/models/DefaultParams.js +27 -0
- package/dist/cjs/src/nanotdf/models/EcCurves.js +39 -0
- package/dist/cjs/src/nanotdf/models/Header.js +255 -0
- package/dist/cjs/src/nanotdf/models/Payload.js +158 -0
- package/dist/cjs/src/nanotdf/models/Policy/AbstractPolicy.js +73 -0
- package/dist/cjs/src/nanotdf/models/Policy/EmbeddedPolicy.js +82 -0
- package/dist/cjs/src/nanotdf/models/Policy/PolicyFactory.js +38 -0
- package/dist/cjs/src/nanotdf/models/Policy/RemotePolicy.js +62 -0
- package/dist/cjs/src/nanotdf/models/ResourceLocator.js +211 -0
- package/dist/cjs/src/nanotdf/models/Signature.js +77 -0
- package/dist/cjs/src/nanotdf-crypto/ciphers.js +17 -0
- package/dist/cjs/src/nanotdf-crypto/decrypt.js +24 -0
- package/dist/cjs/src/nanotdf-crypto/digest.js +7 -0
- package/dist/cjs/src/nanotdf-crypto/ecdsaSignature.js +83 -0
- package/dist/cjs/src/nanotdf-crypto/encrypt.js +24 -0
- package/dist/cjs/src/nanotdf-crypto/enums.js +52 -0
- package/dist/cjs/src/nanotdf-crypto/exportCryptoKey.js +20 -0
- package/dist/cjs/src/nanotdf-crypto/generateKeyPair.js +13 -0
- package/dist/cjs/src/nanotdf-crypto/generateRandomNumber.js +12 -0
- package/dist/cjs/src/nanotdf-crypto/importRawKey.js +18 -0
- package/dist/cjs/src/nanotdf-crypto/index.js +52 -0
- package/dist/cjs/src/nanotdf-crypto/keyAgreement.js +91 -0
- package/dist/cjs/src/nanotdf-crypto/pemPublicToCrypto.js +225 -0
- package/dist/cjs/src/policy/api.js +58 -0
- package/dist/cjs/src/policy/attributes.js +3 -0
- package/dist/cjs/src/policy/granter.js +146 -0
- package/dist/cjs/src/tdf/AttributeObject.js +15 -0
- package/dist/cjs/src/tdf/AttributeObjectJwt.js +3 -0
- package/dist/cjs/src/tdf/Crypto.js +47 -0
- package/dist/cjs/src/tdf/EntityObject.js +3 -0
- package/dist/cjs/src/tdf/NanoTDF/NanoTDF.js +38 -0
- package/dist/cjs/src/tdf/Policy.js +50 -0
- package/dist/cjs/src/tdf/PolicyObject.js +3 -0
- package/dist/cjs/src/tdf/TypedArray.js +3 -0
- package/dist/cjs/src/tdf/index.js +35 -0
- package/dist/cjs/src/types/index.js +3 -0
- package/dist/cjs/src/utils.js +147 -0
- package/dist/cjs/src/version.js +12 -0
- package/dist/cjs/tdf3/index.js +57 -0
- package/dist/cjs/tdf3/src/assertions.js +118 -0
- package/dist/cjs/tdf3/src/binary.js +153 -0
- package/dist/cjs/tdf3/src/ciphers/aes-gcm-cipher.js +56 -0
- package/dist/cjs/tdf3/src/ciphers/algorithms.js +8 -0
- package/dist/cjs/tdf3/src/ciphers/index.js +8 -0
- package/dist/cjs/tdf3/src/ciphers/symmetric-cipher-base.js +22 -0
- package/dist/cjs/tdf3/src/client/DecoratedReadableStream.js +116 -0
- package/dist/cjs/tdf3/src/client/builders.js +561 -0
- package/dist/cjs/tdf3/src/client/index.js +460 -0
- package/dist/cjs/tdf3/src/client/validation.js +63 -0
- package/dist/cjs/tdf3/src/crypto/crypto-utils.js +116 -0
- package/dist/cjs/tdf3/src/crypto/declarations.js +8 -0
- package/dist/cjs/tdf3/src/crypto/index.js +315 -0
- package/dist/cjs/tdf3/src/index.js +34 -0
- package/dist/cjs/tdf3/src/models/attribute-set.js +122 -0
- package/dist/cjs/tdf3/src/models/encryption-information.js +90 -0
- package/dist/cjs/tdf3/src/models/index.js +25 -0
- package/dist/cjs/tdf3/src/models/key-access.js +103 -0
- package/dist/cjs/tdf3/src/models/manifest.js +3 -0
- package/dist/cjs/tdf3/src/models/payload.js +3 -0
- package/dist/cjs/tdf3/src/models/policy.js +24 -0
- package/dist/cjs/tdf3/src/models/upsert-response.js +3 -0
- package/dist/cjs/tdf3/src/tdf.js +907 -0
- package/dist/cjs/tdf3/src/templates/default.html.js +98 -0
- package/dist/cjs/tdf3/src/templates/escaper.js +15 -0
- package/dist/cjs/tdf3/src/templates/index.js +12 -0
- package/dist/cjs/tdf3/src/utils/buffer-crc32.js +48 -0
- package/dist/cjs/tdf3/src/utils/chunkers.js +106 -0
- package/dist/cjs/tdf3/src/utils/index.js +296 -0
- package/dist/cjs/tdf3/src/utils/keysplit.js +61 -0
- package/dist/cjs/tdf3/src/utils/zip-reader.js +253 -0
- package/dist/cjs/tdf3/src/utils/zip-writer.js +308 -0
- package/dist/cjs/tdf3/src/version.js +6 -0
- package/dist/types/src/access.d.ts +47 -0
- package/dist/types/src/access.d.ts.map +1 -0
- package/dist/types/src/auth/Eas.d.ts +34 -0
- package/dist/types/src/auth/Eas.d.ts.map +1 -0
- package/dist/types/src/auth/auth.d.ts +86 -0
- package/dist/types/src/auth/auth.d.ts.map +1 -0
- package/dist/types/src/auth/oidc-clientcredentials-provider.d.ts +9 -0
- package/dist/types/src/auth/oidc-clientcredentials-provider.d.ts.map +1 -0
- package/dist/types/src/auth/oidc-externaljwt-provider.d.ts +10 -0
- package/dist/types/src/auth/oidc-externaljwt-provider.d.ts.map +1 -0
- package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts +10 -0
- package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts.map +1 -0
- package/dist/types/src/auth/oidc.d.ts +104 -0
- package/dist/types/src/auth/oidc.d.ts.map +1 -0
- package/dist/types/src/auth/providers.d.ts +67 -0
- package/dist/types/src/auth/providers.d.ts.map +1 -0
- package/dist/types/src/encodings/base64.d.ts +18 -0
- package/dist/types/src/encodings/base64.d.ts.map +1 -0
- package/dist/types/src/encodings/hex.d.ts +5 -0
- package/dist/types/src/encodings/hex.d.ts.map +1 -0
- package/dist/types/src/encodings/index.d.ts +3 -0
- package/dist/types/src/encodings/index.d.ts.map +1 -0
- package/dist/types/src/errors.d.ts +72 -0
- package/dist/types/src/errors.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +138 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/nanotdf/Client.d.ts +95 -0
- package/dist/types/src/nanotdf/Client.d.ts.map +1 -0
- package/dist/types/src/nanotdf/NanoTDF.d.ts +25 -0
- package/dist/types/src/nanotdf/NanoTDF.d.ts.map +1 -0
- package/dist/types/src/nanotdf/browser-entry.d.ts +17 -0
- package/dist/types/src/nanotdf/browser-entry.d.ts.map +1 -0
- package/dist/types/src/nanotdf/constants.d.ts +2 -0
- package/dist/types/src/nanotdf/constants.d.ts.map +1 -0
- package/dist/types/src/nanotdf/decrypt.d.ts +9 -0
- package/dist/types/src/nanotdf/decrypt.d.ts.map +1 -0
- package/dist/types/src/nanotdf/encrypt-dataset.d.ts +12 -0
- package/dist/types/src/nanotdf/encrypt-dataset.d.ts.map +1 -0
- package/dist/types/src/nanotdf/encrypt.d.ts +14 -0
- package/dist/types/src/nanotdf/encrypt.d.ts.map +1 -0
- package/dist/types/src/nanotdf/enum/CipherEnum.d.ts +10 -0
- package/dist/types/src/nanotdf/enum/CipherEnum.d.ts.map +1 -0
- package/dist/types/src/nanotdf/enum/CurveNameEnum.d.ts +12 -0
- package/dist/types/src/nanotdf/enum/CurveNameEnum.d.ts.map +1 -0
- package/dist/types/src/nanotdf/enum/EncodingEnum.d.ts +5 -0
- package/dist/types/src/nanotdf/enum/EncodingEnum.d.ts.map +1 -0
- package/dist/types/src/nanotdf/enum/PolicyTypeEnum.d.ts +8 -0
- package/dist/types/src/nanotdf/enum/PolicyTypeEnum.d.ts.map +1 -0
- package/dist/types/src/nanotdf/enum/ProtocolEnum.d.ts +7 -0
- package/dist/types/src/nanotdf/enum/ProtocolEnum.d.ts.map +1 -0
- package/dist/types/src/nanotdf/enum/ResourceLocatorIdentifierEnum.d.ts +8 -0
- package/dist/types/src/nanotdf/enum/ResourceLocatorIdentifierEnum.d.ts.map +1 -0
- package/dist/types/src/nanotdf/helpers/calculateByCurve.d.ts +20 -0
- package/dist/types/src/nanotdf/helpers/calculateByCurve.d.ts.map +1 -0
- package/dist/types/src/nanotdf/helpers/getHkdfSalt.d.ts +9 -0
- package/dist/types/src/nanotdf/helpers/getHkdfSalt.d.ts.map +1 -0
- package/dist/types/src/nanotdf/index.d.ts +9 -0
- package/dist/types/src/nanotdf/index.d.ts.map +1 -0
- package/dist/types/src/nanotdf/interfaces/PolicyInterface.d.ts +17 -0
- package/dist/types/src/nanotdf/interfaces/PolicyInterface.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Ciphers.d.ts +14 -0
- package/dist/types/src/nanotdf/models/Ciphers.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/DefaultParams.d.ts +21 -0
- package/dist/types/src/nanotdf/models/DefaultParams.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/EcCurves.d.ts +15 -0
- package/dist/types/src/nanotdf/models/EcCurves.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Header.d.ts +73 -0
- package/dist/types/src/nanotdf/models/Header.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Payload.d.ts +47 -0
- package/dist/types/src/nanotdf/models/Payload.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Policy/AbstractPolicy.d.ts +52 -0
- package/dist/types/src/nanotdf/models/Policy/AbstractPolicy.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Policy/EmbeddedPolicy.d.ts +35 -0
- package/dist/types/src/nanotdf/models/Policy/EmbeddedPolicy.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Policy/PolicyFactory.d.ts +11 -0
- package/dist/types/src/nanotdf/models/Policy/PolicyFactory.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Policy/RemotePolicy.d.ts +31 -0
- package/dist/types/src/nanotdf/models/Policy/RemotePolicy.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/ResourceLocator.d.ts +65 -0
- package/dist/types/src/nanotdf/models/ResourceLocator.d.ts.map +1 -0
- package/dist/types/src/nanotdf/models/Signature.d.ts +33 -0
- package/dist/types/src/nanotdf/models/Signature.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/ciphers.d.ts +8 -0
- package/dist/types/src/nanotdf-crypto/ciphers.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/decrypt.d.ts +14 -0
- package/dist/types/src/nanotdf-crypto/decrypt.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/digest.d.ts +3 -0
- package/dist/types/src/nanotdf-crypto/digest.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/ecdsaSignature.d.ts +35 -0
- package/dist/types/src/nanotdf-crypto/ecdsaSignature.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/encrypt.d.ts +14 -0
- package/dist/types/src/nanotdf-crypto/encrypt.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/enums.d.ts +42 -0
- package/dist/types/src/nanotdf-crypto/enums.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/exportCryptoKey.d.ts +7 -0
- package/dist/types/src/nanotdf-crypto/exportCryptoKey.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/generateKeyPair.d.ts +10 -0
- package/dist/types/src/nanotdf-crypto/generateKeyPair.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/generateRandomNumber.d.ts +5 -0
- package/dist/types/src/nanotdf-crypto/generateRandomNumber.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/importRawKey.d.ts +13 -0
- package/dist/types/src/nanotdf-crypto/importRawKey.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/index.d.ts +12 -0
- package/dist/types/src/nanotdf-crypto/index.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/keyAgreement.d.ts +28 -0
- package/dist/types/src/nanotdf-crypto/keyAgreement.d.ts.map +1 -0
- package/dist/types/src/nanotdf-crypto/pemPublicToCrypto.d.ts +28 -0
- package/dist/types/src/nanotdf-crypto/pemPublicToCrypto.d.ts.map +1 -0
- package/dist/types/src/policy/api.d.ts +4 -0
- package/dist/types/src/policy/api.d.ts.map +1 -0
- package/dist/types/src/policy/attributes.d.ts +95 -0
- package/dist/types/src/policy/attributes.d.ts.map +1 -0
- package/dist/types/src/policy/granter.d.ts +23 -0
- package/dist/types/src/policy/granter.d.ts.map +1 -0
- package/dist/types/src/tdf/AttributeObject.d.ts +13 -0
- package/dist/types/src/tdf/AttributeObject.d.ts.map +1 -0
- package/dist/types/src/tdf/AttributeObjectJwt.d.ts +4 -0
- package/dist/types/src/tdf/AttributeObjectJwt.d.ts.map +1 -0
- package/dist/types/src/tdf/Crypto.d.ts +37 -0
- package/dist/types/src/tdf/Crypto.d.ts.map +1 -0
- package/dist/types/src/tdf/EntityObject.d.ts +18 -0
- package/dist/types/src/tdf/EntityObject.d.ts.map +1 -0
- package/dist/types/src/tdf/NanoTDF/NanoTDF.d.ts +99 -0
- package/dist/types/src/tdf/NanoTDF/NanoTDF.d.ts.map +1 -0
- package/dist/types/src/tdf/Policy.d.ts +28 -0
- package/dist/types/src/tdf/Policy.d.ts.map +1 -0
- package/dist/types/src/tdf/PolicyObject.d.ts +11 -0
- package/dist/types/src/tdf/PolicyObject.d.ts.map +1 -0
- package/dist/types/src/tdf/TypedArray.d.ts +3 -0
- package/dist/types/src/tdf/TypedArray.d.ts.map +1 -0
- package/dist/types/src/tdf/index.d.ts +7 -0
- package/dist/types/src/tdf/index.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +45 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/utils.d.ts +45 -0
- package/dist/types/src/utils.d.ts.map +1 -0
- package/dist/types/src/version.d.ts +9 -0
- package/dist/types/src/version.d.ts.map +1 -0
- package/dist/types/tdf3/index.d.ts +16 -0
- package/dist/types/tdf3/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/assertions.d.ts +63 -0
- package/dist/types/tdf3/src/assertions.d.ts.map +1 -0
- package/dist/types/tdf3/src/binary.d.ts +38 -0
- package/dist/types/tdf3/src/binary.d.ts.map +1 -0
- package/dist/types/tdf3/src/ciphers/aes-gcm-cipher.d.ts +18 -0
- package/dist/types/tdf3/src/ciphers/aes-gcm-cipher.d.ts.map +1 -0
- package/dist/types/tdf3/src/ciphers/algorithms.d.ts +4 -0
- package/dist/types/tdf3/src/ciphers/algorithms.d.ts.map +1 -0
- package/dist/types/tdf3/src/ciphers/index.d.ts +3 -0
- package/dist/types/tdf3/src/ciphers/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/ciphers/symmetric-cipher-base.d.ts +14 -0
- package/dist/types/tdf3/src/ciphers/symmetric-cipher-base.d.ts.map +1 -0
- package/dist/types/tdf3/src/client/DecoratedReadableStream.d.ts +53 -0
- package/dist/types/tdf3/src/client/DecoratedReadableStream.d.ts.map +1 -0
- package/dist/types/tdf3/src/client/builders.d.ts +436 -0
- package/dist/types/tdf3/src/client/builders.d.ts.map +1 -0
- package/dist/types/tdf3/src/client/index.d.ts +139 -0
- package/dist/types/tdf3/src/client/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/client/validation.d.ts +8 -0
- package/dist/types/tdf3/src/client/validation.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/crypto-utils.d.ts +34 -0
- package/dist/types/tdf3/src/crypto/crypto-utils.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/declarations.d.ts +60 -0
- package/dist/types/tdf3/src/crypto/declarations.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/index.d.ts +103 -0
- package/dist/types/tdf3/src/crypto/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/index.d.ts +5 -0
- package/dist/types/tdf3/src/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/attribute-set.d.ts +65 -0
- package/dist/types/tdf3/src/models/attribute-set.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/encryption-information.d.ts +49 -0
- package/dist/types/tdf3/src/models/encryption-information.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/index.d.ts +9 -0
- package/dist/types/tdf3/src/models/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/key-access.d.ts +42 -0
- package/dist/types/tdf3/src/models/key-access.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/manifest.d.ts +9 -0
- package/dist/types/tdf3/src/models/manifest.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/payload.d.ts +7 -0
- package/dist/types/tdf3/src/models/payload.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/policy.d.ts +13 -0
- package/dist/types/tdf3/src/models/policy.d.ts.map +1 -0
- package/dist/types/tdf3/src/models/upsert-response.d.ts +16 -0
- package/dist/types/tdf3/src/models/upsert-response.d.ts.map +1 -0
- package/dist/types/tdf3/src/tdf.d.ts +152 -0
- package/dist/types/tdf3/src/tdf.d.ts.map +1 -0
- package/dist/types/tdf3/src/templates/default.html.d.ts +8 -0
- package/dist/types/tdf3/src/templates/default.html.d.ts.map +1 -0
- package/dist/types/tdf3/src/templates/escaper.d.ts +6 -0
- package/dist/types/tdf3/src/templates/escaper.d.ts.map +1 -0
- package/dist/types/tdf3/src/templates/index.d.ts +3 -0
- package/dist/types/tdf3/src/templates/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/utils/buffer-crc32.d.ts +2 -0
- package/dist/types/tdf3/src/utils/buffer-crc32.d.ts.map +1 -0
- package/dist/types/tdf3/src/utils/chunkers.d.ts +29 -0
- package/dist/types/tdf3/src/utils/chunkers.d.ts.map +1 -0
- package/dist/types/tdf3/src/utils/index.d.ts +36 -0
- package/dist/types/tdf3/src/utils/index.d.ts.map +1 -0
- package/dist/types/tdf3/src/utils/keysplit.d.ts +19 -0
- package/dist/types/tdf3/src/utils/keysplit.d.ts.map +1 -0
- package/dist/types/tdf3/src/utils/zip-reader.d.ts +63 -0
- package/dist/types/tdf3/src/utils/zip-reader.d.ts.map +1 -0
- package/dist/types/tdf3/src/utils/zip-writer.d.ts +35 -0
- package/dist/types/tdf3/src/utils/zip-writer.d.ts.map +1 -0
- package/dist/types/tdf3/src/version.d.ts +3 -0
- package/dist/types/tdf3/src/version.d.ts.map +1 -0
- package/dist/web/package.json +3 -0
- package/dist/web/src/access.js +147 -0
- package/dist/web/src/auth/Eas.js +55 -0
- package/dist/web/src/auth/auth.js +71 -0
- package/dist/web/src/auth/oidc-clientcredentials-provider.js +22 -0
- package/dist/web/src/auth/oidc-externaljwt-provider.js +29 -0
- package/dist/web/src/auth/oidc-refreshtoken-provider.js +30 -0
- package/dist/web/src/auth/oidc.js +215 -0
- package/dist/web/src/auth/providers.js +119 -0
- package/dist/web/src/encodings/base64.js +147 -0
- package/dist/web/src/encodings/hex.js +63 -0
- package/dist/web/src/encodings/index.js +3 -0
- package/dist/web/src/errors.js +123 -0
- package/dist/web/src/index.js +313 -0
- package/dist/web/src/nanotdf/Client.js +268 -0
- package/dist/web/src/nanotdf/NanoTDF.js +89 -0
- package/dist/web/src/nanotdf/browser-entry.js +14 -0
- package/dist/web/src/nanotdf/constants.js +2 -0
- package/dist/web/src/nanotdf/decrypt.js +14 -0
- package/dist/web/src/nanotdf/encrypt-dataset.js +32 -0
- package/dist/web/src/nanotdf/encrypt.js +126 -0
- package/dist/web/src/nanotdf/enum/CipherEnum.js +11 -0
- package/dist/web/src/nanotdf/enum/CurveNameEnum.js +13 -0
- package/dist/web/src/nanotdf/enum/EncodingEnum.js +6 -0
- package/dist/web/src/nanotdf/enum/PolicyTypeEnum.js +9 -0
- package/dist/web/src/nanotdf/enum/ProtocolEnum.js +8 -0
- package/dist/web/src/nanotdf/enum/ResourceLocatorIdentifierEnum.js +9 -0
- package/dist/web/src/nanotdf/helpers/calculateByCurve.js +24 -0
- package/dist/web/src/nanotdf/helpers/getHkdfSalt.js +8 -0
- package/dist/web/src/nanotdf/index.js +11 -0
- package/dist/web/src/nanotdf/interfaces/PolicyInterface.js +2 -0
- package/dist/web/src/nanotdf/models/Ciphers.js +54 -0
- package/dist/web/src/nanotdf/models/DefaultParams.js +22 -0
- package/dist/web/src/nanotdf/models/EcCurves.js +32 -0
- package/dist/web/src/nanotdf/models/Header.js +250 -0
- package/dist/web/src/nanotdf/models/Payload.js +156 -0
- package/dist/web/src/nanotdf/models/Policy/AbstractPolicy.js +71 -0
- package/dist/web/src/nanotdf/models/Policy/EmbeddedPolicy.js +77 -0
- package/dist/web/src/nanotdf/models/Policy/PolicyFactory.js +33 -0
- package/dist/web/src/nanotdf/models/Policy/RemotePolicy.js +57 -0
- package/dist/web/src/nanotdf/models/ResourceLocator.js +206 -0
- package/dist/web/src/nanotdf/models/Signature.js +74 -0
- package/dist/web/src/nanotdf-crypto/ciphers.js +14 -0
- package/dist/web/src/nanotdf-crypto/decrypt.js +21 -0
- package/dist/web/src/nanotdf-crypto/digest.js +4 -0
- package/dist/web/src/nanotdf-crypto/ecdsaSignature.js +77 -0
- package/dist/web/src/nanotdf-crypto/encrypt.js +21 -0
- package/dist/web/src/nanotdf-crypto/enums.js +49 -0
- package/dist/web/src/nanotdf-crypto/exportCryptoKey.js +17 -0
- package/dist/web/src/nanotdf-crypto/generateKeyPair.js +10 -0
- package/dist/web/src/nanotdf-crypto/generateRandomNumber.js +9 -0
- package/dist/web/src/nanotdf-crypto/importRawKey.js +15 -0
- package/dist/web/src/nanotdf-crypto/index.js +12 -0
- package/dist/web/src/nanotdf-crypto/keyAgreement.js +87 -0
- package/dist/web/src/nanotdf-crypto/pemPublicToCrypto.js +197 -0
- package/dist/web/src/policy/api.js +54 -0
- package/dist/web/src/policy/attributes.js +2 -0
- package/dist/web/src/policy/granter.js +141 -0
- package/dist/web/src/tdf/AttributeObject.js +11 -0
- package/dist/web/src/tdf/AttributeObjectJwt.js +2 -0
- package/dist/web/src/tdf/Crypto.js +44 -0
- package/dist/web/src/tdf/EntityObject.js +2 -0
- package/dist/web/src/tdf/NanoTDF/NanoTDF.js +35 -0
- package/dist/web/src/tdf/Policy.js +48 -0
- package/dist/web/src/tdf/PolicyObject.js +2 -0
- package/dist/web/src/tdf/TypedArray.js +2 -0
- package/dist/web/src/tdf/index.js +4 -0
- package/dist/web/src/types/index.js +2 -0
- package/dist/web/src/utils.js +133 -0
- package/dist/web/src/version.js +9 -0
- package/dist/web/tdf3/index.js +13 -0
- package/dist/web/tdf3/src/assertions.js +111 -0
- package/dist/web/tdf3/src/binary.js +149 -0
- package/dist/web/tdf3/src/ciphers/aes-gcm-cipher.js +52 -0
- package/dist/web/tdf3/src/ciphers/algorithms.js +5 -0
- package/dist/web/tdf3/src/ciphers/index.js +3 -0
- package/dist/web/tdf3/src/ciphers/symmetric-cipher-base.js +18 -0
- package/dist/web/tdf3/src/client/DecoratedReadableStream.js +107 -0
- package/dist/web/tdf3/src/client/builders.js +557 -0
- package/dist/web/tdf3/src/client/index.js +423 -0
- package/dist/web/tdf3/src/client/validation.js +58 -0
- package/dist/web/tdf3/src/crypto/crypto-utils.js +107 -0
- package/dist/web/tdf3/src/crypto/declarations.js +5 -0
- package/dist/web/tdf3/src/crypto/index.js +296 -0
- package/dist/web/tdf3/src/index.js +5 -0
- package/dist/web/tdf3/src/models/attribute-set.js +118 -0
- package/dist/web/tdf3/src/models/encryption-information.js +86 -0
- package/dist/web/tdf3/src/models/index.js +9 -0
- package/dist/web/tdf3/src/models/key-access.js +74 -0
- package/dist/web/tdf3/src/models/manifest.js +2 -0
- package/dist/web/tdf3/src/models/payload.js +2 -0
- package/dist/web/tdf3/src/models/policy.js +20 -0
- package/dist/web/tdf3/src/models/upsert-response.js +2 -0
- package/dist/web/tdf3/src/tdf.js +866 -0
- package/dist/web/tdf3/src/templates/default.html.js +96 -0
- package/dist/web/tdf3/src/templates/escaper.js +10 -0
- package/dist/web/tdf3/src/templates/index.js +3 -0
- package/dist/web/tdf3/src/utils/buffer-crc32.js +44 -0
- package/dist/web/tdf3/src/utils/chunkers.js +96 -0
- package/dist/web/tdf3/src/utils/index.js +248 -0
- package/dist/web/tdf3/src/utils/keysplit.js +55 -0
- package/dist/web/tdf3/src/utils/zip-reader.js +247 -0
- package/dist/web/tdf3/src/utils/zip-writer.js +302 -0
- package/dist/web/tdf3/src/version.js +3 -0
- package/package.json +126 -0
- package/src/access.ts +198 -0
- package/src/auth/Eas.ts +79 -0
- package/src/auth/auth.ts +141 -0
- package/src/auth/oidc-clientcredentials-provider.ts +32 -0
- package/src/auth/oidc-externaljwt-provider.ts +41 -0
- package/src/auth/oidc-refreshtoken-provider.ts +41 -0
- package/src/auth/oidc.ts +307 -0
- package/src/auth/providers.ts +139 -0
- package/src/encodings/base64.ts +160 -0
- package/src/encodings/hex.ts +69 -0
- package/src/encodings/index.ts +2 -0
- package/src/errors.ts +113 -0
- package/src/index.ts +441 -0
- package/src/nanotdf/Client.ts +349 -0
- package/src/nanotdf/NanoTDF.ts +121 -0
- package/src/nanotdf/browser-entry.ts +20 -0
- package/src/nanotdf/constants.ts +1 -0
- package/src/nanotdf/decrypt.ts +19 -0
- package/src/nanotdf/encrypt-dataset.ts +52 -0
- package/src/nanotdf/encrypt.ts +197 -0
- package/src/nanotdf/enum/CipherEnum.ts +10 -0
- package/src/nanotdf/enum/CurveNameEnum.ts +12 -0
- package/src/nanotdf/enum/EncodingEnum.ts +5 -0
- package/src/nanotdf/enum/PolicyTypeEnum.ts +8 -0
- package/src/nanotdf/enum/ProtocolEnum.ts +7 -0
- package/src/nanotdf/enum/ResourceLocatorIdentifierEnum.ts +8 -0
- package/src/nanotdf/helpers/calculateByCurve.ts +26 -0
- package/src/nanotdf/helpers/getHkdfSalt.ts +15 -0
- package/src/nanotdf/index.ts +10 -0
- package/src/nanotdf/interfaces/PolicyInterface.ts +27 -0
- package/src/nanotdf/models/Ciphers.ts +67 -0
- package/src/nanotdf/models/DefaultParams.ts +24 -0
- package/src/nanotdf/models/EcCurves.ts +40 -0
- package/src/nanotdf/models/Header.ts +322 -0
- package/src/nanotdf/models/Payload.ts +196 -0
- package/src/nanotdf/models/Policy/AbstractPolicy.ts +90 -0
- package/src/nanotdf/models/Policy/EmbeddedPolicy.ts +101 -0
- package/src/nanotdf/models/Policy/PolicyFactory.ts +48 -0
- package/src/nanotdf/models/Policy/RemotePolicy.ts +74 -0
- package/src/nanotdf/models/ResourceLocator.ts +212 -0
- package/src/nanotdf/models/Signature.ts +85 -0
- package/src/nanotdf-crypto/ciphers.ts +13 -0
- package/src/nanotdf-crypto/decrypt.ts +30 -0
- package/src/nanotdf-crypto/digest.ts +8 -0
- package/src/nanotdf-crypto/ecdsaSignature.ts +109 -0
- package/src/nanotdf-crypto/encrypt.ts +30 -0
- package/src/nanotdf-crypto/enums.ts +47 -0
- package/src/nanotdf-crypto/exportCryptoKey.ts +17 -0
- package/src/nanotdf-crypto/generateKeyPair.ts +19 -0
- package/src/nanotdf-crypto/generateRandomNumber.ts +8 -0
- package/src/nanotdf-crypto/importRawKey.ts +19 -0
- package/src/nanotdf-crypto/index.ts +11 -0
- package/src/nanotdf-crypto/keyAgreement.ts +139 -0
- package/src/nanotdf-crypto/pemPublicToCrypto.ts +232 -0
- package/src/package-lock.json +6 -0
- package/src/package.json +3 -0
- package/src/platform/authorization/authorization_connect.d.ts +44 -0
- package/src/platform/authorization/authorization_connect.js +44 -0
- package/src/platform/authorization/authorization_pb.d.ts +707 -0
- package/src/platform/authorization/authorization_pb.js +372 -0
- package/src/platform/common/common_pb.d.ts +129 -0
- package/src/platform/common/common_pb.js +58 -0
- package/src/platform/entityresolution/entity_resolution_connect.d.ts +35 -0
- package/src/platform/entityresolution/entity_resolution_connect.js +35 -0
- package/src/platform/entityresolution/entity_resolution_pb.d.ts +242 -0
- package/src/platform/entityresolution/entity_resolution_pb.js +139 -0
- package/src/platform/kas/kas_connect.d.ts +59 -0
- package/src/platform/kas/kas_connect.js +59 -0
- package/src/platform/kas/kas_pb.d.ts +200 -0
- package/src/platform/kas/kas_pb.js +84 -0
- package/src/platform/policy/attributes/attributes_connect.d.ts +168 -0
- package/src/platform/policy/attributes/attributes_connect.js +168 -0
- package/src/platform/policy/attributes/attributes_pb.d.ts +929 -0
- package/src/platform/policy/attributes/attributes_pb.js +363 -0
- package/src/platform/policy/kasregistry/key_access_server_registry_connect.d.ts +62 -0
- package/src/platform/policy/kasregistry/key_access_server_registry_connect.js +62 -0
- package/src/platform/policy/kasregistry/key_access_server_registry_pb.d.ts +283 -0
- package/src/platform/policy/kasregistry/key_access_server_registry_pb.js +113 -0
- package/src/platform/policy/namespaces/namespaces_connect.d.ts +62 -0
- package/src/platform/policy/namespaces/namespaces_connect.js +62 -0
- package/src/platform/policy/namespaces/namespaces_pb.d.ts +270 -0
- package/src/platform/policy/namespaces/namespaces_pb.js +110 -0
- package/src/platform/policy/objects_pb.d.ts +725 -0
- package/src/platform/policy/objects_pb.js +288 -0
- package/src/platform/policy/resourcemapping/resource_mapping_connect.d.ts +259 -0
- package/src/platform/policy/resourcemapping/resource_mapping_connect.js +259 -0
- package/src/platform/policy/resourcemapping/resource_mapping_pb.d.ts +314 -0
- package/src/platform/policy/resourcemapping/resource_mapping_pb.js +142 -0
- package/src/platform/policy/selectors_pb.d.ts +269 -0
- package/src/platform/policy/selectors_pb.js +110 -0
- package/src/platform/policy/subjectmapping/subject_mapping_connect.d.ts +118 -0
- package/src/platform/policy/subjectmapping/subject_mapping_connect.js +118 -0
- package/src/platform/policy/subjectmapping/subject_mapping_pb.d.ts +672 -0
- package/src/platform/policy/subjectmapping/subject_mapping_pb.js +260 -0
- package/src/platform/wellknownconfiguration/wellknown_configuration_connect.d.ts +26 -0
- package/src/platform/wellknownconfiguration/wellknown_configuration_connect.js +26 -0
- package/src/platform/wellknownconfiguration/wellknown_configuration_pb.d.ts +75 -0
- package/src/platform/wellknownconfiguration/wellknown_configuration_pb.js +35 -0
- package/src/policy/api.ts +61 -0
- package/src/policy/attributes.ts +117 -0
- package/src/policy/granter.ts +181 -0
- package/src/tdf/AttributeObject.ts +27 -0
- package/src/tdf/AttributeObjectJwt.ts +3 -0
- package/src/tdf/Crypto.ts +42 -0
- package/src/tdf/EntityObject.ts +18 -0
- package/src/tdf/NanoTDF/NanoTDF.ts +120 -0
- package/src/tdf/Policy.ts +51 -0
- package/src/tdf/PolicyObject.ts +12 -0
- package/src/tdf/TypedArray.ts +12 -0
- package/src/tdf/index.ts +6 -0
- package/src/types/index.ts +55 -0
- package/src/utils.ts +149 -0
- package/src/version.ts +9 -0
- package/tdf3/index.ts +91 -0
- package/tdf3/package-lock.json +6 -0
- package/tdf3/package.json +3 -0
- package/tdf3/src/assertions.ts +191 -0
- package/tdf3/src/binary.ts +195 -0
- package/tdf3/src/ciphers/aes-gcm-cipher.ts +76 -0
- package/tdf3/src/ciphers/algorithms.ts +9 -0
- package/tdf3/src/ciphers/index.ts +2 -0
- package/tdf3/src/ciphers/symmetric-cipher-base.ts +38 -0
- package/tdf3/src/client/DecoratedReadableStream.ts +148 -0
- package/tdf3/src/client/builders.ts +701 -0
- package/tdf3/src/client/index.ts +637 -0
- package/tdf3/src/client/validation.ts +79 -0
- package/tdf3/src/crypto/crypto-utils.ts +119 -0
- package/tdf3/src/crypto/declarations.ts +89 -0
- package/tdf3/src/crypto/index.ts +394 -0
- package/tdf3/src/index.ts +4 -0
- package/tdf3/src/models/attribute-set.ts +142 -0
- package/tdf3/src/models/encryption-information.ts +172 -0
- package/tdf3/src/models/index.ts +8 -0
- package/tdf3/src/models/key-access.ts +128 -0
- package/tdf3/src/models/manifest.ts +9 -0
- package/tdf3/src/models/payload.ts +6 -0
- package/tdf3/src/models/policy.ts +35 -0
- package/tdf3/src/models/upsert-response.ts +17 -0
- package/tdf3/src/tdf.ts +1351 -0
- package/tdf3/src/templates/default.html.ts +105 -0
- package/tdf3/src/templates/escaper.ts +10 -0
- package/tdf3/src/templates/index.ts +2 -0
- package/tdf3/src/utils/buffer-crc32.ts +46 -0
- package/tdf3/src/utils/chunkers.ts +118 -0
- package/tdf3/src/utils/index.ts +309 -0
- package/tdf3/src/utils/keysplit.ts +63 -0
- package/tdf3/src/utils/zip-reader.ts +341 -0
- package/tdf3/src/utils/zip-writer.ts +375 -0
- package/tdf3/src/version.ts +2 -0
- package/tdf3/types.d.ts +14 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
import { v4 } from 'uuid';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { ZipReader, fromBuffer, fromDataSource, streamToBuffer, isAppIdProviderCheck, keyMiddleware as defaultKeyMiddleware, } from '../utils/index.js';
|
|
4
|
+
import { base64 } from '../../../src/encodings/index.js';
|
|
5
|
+
import { buildKeyAccess, fetchKasPublicKey, loadTDFStream, unwrapHtml, validatePolicyObject, readStream, wrapHtml, writeStream, } from '../tdf.js';
|
|
6
|
+
import { OIDCRefreshTokenProvider } from '../../../src/auth/oidc-refreshtoken-provider.js';
|
|
7
|
+
import { OIDCExternalJwtProvider } from '../../../src/auth/oidc-externaljwt-provider.js';
|
|
8
|
+
import { AppIdAuthProvider, HttpRequest, withHeaders, } from '../../../src/auth/auth.js';
|
|
9
|
+
import EAS from '../../../src/auth/Eas.js';
|
|
10
|
+
import { cryptoPublicToPem, pemToCryptoPublicKey, rstrip, validateSecureUrl, } from '../../../src/utils.js';
|
|
11
|
+
import { DecoratedReadableStream } from './DecoratedReadableStream.js';
|
|
12
|
+
import { DEFAULT_SEGMENT_SIZE, DecryptParamsBuilder, EncryptParamsBuilder, } from './builders.js';
|
|
13
|
+
import { OriginAllowList } from '../../../src/access.js';
|
|
14
|
+
import { ConfigurationError } from '../../../src/errors.js';
|
|
15
|
+
import { AesGcmCipher } from '../ciphers/aes-gcm-cipher.js';
|
|
16
|
+
import { toCryptoKeyPair } from '../crypto/crypto-utils.js';
|
|
17
|
+
import * as defaultCryptoService from '../crypto/index.js';
|
|
18
|
+
import { AttributeSet, SplitKey } from '../models/index.js';
|
|
19
|
+
import { plan } from '../../../src/policy/granter.js';
|
|
20
|
+
import { attributeFQNsAsValues } from '../../../src/policy/api.js';
|
|
21
|
+
const GLOBAL_BYTE_LIMIT = 64 * 1000 * 1000 * 1000; // 64 GB, see WS-9363.
|
|
22
|
+
const HTML_BYTE_LIMIT = 100 * 1000 * 1000; // 100 MB, see WS-9476.
|
|
23
|
+
// No default config for now. Delegate to Virtru wrapper for endpoints.
|
|
24
|
+
const defaultClientConfig = { oidcOrigin: '', cryptoService: defaultCryptoService };
|
|
25
|
+
export const uploadBinaryToS3 = async function (stream, uploadUrl, fileSize) {
|
|
26
|
+
try {
|
|
27
|
+
const body = await streamToBuffer(stream);
|
|
28
|
+
await axios.put(uploadUrl, body, {
|
|
29
|
+
headers: {
|
|
30
|
+
'Content-Length': fileSize,
|
|
31
|
+
'content-type': 'application/zip',
|
|
32
|
+
'cache-control': 'no-store',
|
|
33
|
+
},
|
|
34
|
+
maxContentLength: Infinity,
|
|
35
|
+
maxBodyLength: Infinity,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
console.error(e);
|
|
40
|
+
throw e;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const getFirstTwoBytes = async (chunker) => new TextDecoder().decode(await chunker(0, 2));
|
|
44
|
+
const makeChunkable = async (source) => {
|
|
45
|
+
if (!source) {
|
|
46
|
+
throw new ConfigurationError('invalid source');
|
|
47
|
+
}
|
|
48
|
+
// dump stream to buffer
|
|
49
|
+
// we don't support streams anyways (see zipreader.js)
|
|
50
|
+
let initialChunker;
|
|
51
|
+
let buf = null;
|
|
52
|
+
switch (source.type) {
|
|
53
|
+
case 'stream':
|
|
54
|
+
buf = await streamToBuffer(source.location);
|
|
55
|
+
initialChunker = fromBuffer(buf);
|
|
56
|
+
break;
|
|
57
|
+
case 'buffer':
|
|
58
|
+
buf = source.location;
|
|
59
|
+
initialChunker = fromBuffer(buf);
|
|
60
|
+
break;
|
|
61
|
+
case 'chunker':
|
|
62
|
+
initialChunker = source.location;
|
|
63
|
+
break;
|
|
64
|
+
default:
|
|
65
|
+
initialChunker = await fromDataSource(source);
|
|
66
|
+
}
|
|
67
|
+
const magic = await getFirstTwoBytes(initialChunker);
|
|
68
|
+
// Pull first two bytes from source.
|
|
69
|
+
if (magic === 'PK') {
|
|
70
|
+
return initialChunker;
|
|
71
|
+
}
|
|
72
|
+
// Unwrap if it's html.
|
|
73
|
+
// If NOT zip (html), convert/dump to buffer, unwrap, and continue.
|
|
74
|
+
const htmlBuf = buf ?? (await initialChunker());
|
|
75
|
+
const zipBuf = unwrapHtml(htmlBuf);
|
|
76
|
+
return fromBuffer(zipBuf);
|
|
77
|
+
};
|
|
78
|
+
/*
|
|
79
|
+
* Extract a keypair provided as part of the options dict.
|
|
80
|
+
* Default to using the clientwide keypair, generating one if necessary.
|
|
81
|
+
*
|
|
82
|
+
* Additionally, update the auth injector with the (potentially new) pubkey
|
|
83
|
+
*/
|
|
84
|
+
export async function createSessionKeys({ authProvider,
|
|
85
|
+
// FIXME use cryptoservice to generate keys again
|
|
86
|
+
cryptoService, dpopKeys, }) {
|
|
87
|
+
let signingKeys;
|
|
88
|
+
if (dpopKeys) {
|
|
89
|
+
signingKeys = await dpopKeys;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const keys = await cryptoService.generateSigningKeyPair();
|
|
93
|
+
// signingKeys = await crypto.subtle.generateKey(rsaPkcs1Sha256(), true, ['sign']);
|
|
94
|
+
signingKeys = await toCryptoKeyPair(keys);
|
|
95
|
+
}
|
|
96
|
+
// This will contact the auth server and forcibly refresh the auth token claims,
|
|
97
|
+
// binding the token and the (new) pubkey together.
|
|
98
|
+
// Note that we base64 encode the PEM string here as a quick workaround, simply because
|
|
99
|
+
// a formatted raw PEM string isn't a valid header value and sending it raw makes keycloak's
|
|
100
|
+
// header parser barf. There are more subtle ways to solve this, but this works for now.
|
|
101
|
+
if (authProvider && !isAppIdProviderCheck(authProvider)) {
|
|
102
|
+
await authProvider?.updateClientPublicKey(signingKeys);
|
|
103
|
+
}
|
|
104
|
+
return signingKeys;
|
|
105
|
+
}
|
|
106
|
+
/*
|
|
107
|
+
* Create a policy object for an encrypt operation.
|
|
108
|
+
*/
|
|
109
|
+
function asPolicy(scope) {
|
|
110
|
+
if (scope.policyObject) {
|
|
111
|
+
// use the client override if provided
|
|
112
|
+
return scope.policyObject;
|
|
113
|
+
}
|
|
114
|
+
const policyId = scope.policyId ?? v4();
|
|
115
|
+
let dataAttributes;
|
|
116
|
+
if (scope.attributeValues) {
|
|
117
|
+
dataAttributes = scope.attributeValues
|
|
118
|
+
.filter(({ fqn }) => !!fqn)
|
|
119
|
+
.map(({ fqn }) => {
|
|
120
|
+
return { attribute: fqn };
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
dataAttributes = (scope.attributes ?? []).map((attribute) => typeof attribute === 'string' ? { attribute } : attribute);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
uuid: policyId,
|
|
128
|
+
body: {
|
|
129
|
+
dataAttributes,
|
|
130
|
+
dissem: scope.dissem ?? [],
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export class Client {
|
|
135
|
+
/**
|
|
136
|
+
* An abstraction for protecting and accessing data using TDF3 services.
|
|
137
|
+
* @param {Object} [config.keypair] - keypair generated for signing. Optional, will be generated by sdk if not passed
|
|
138
|
+
* @param {String} [config.clientId]
|
|
139
|
+
* @param {String} [config.kasEndpoint] - Key Access Server url
|
|
140
|
+
* @param {String} [config.refreshToken] - After logging in to browser OIDC interface user
|
|
141
|
+
* receives fresh token that needed by SDK for auth needs
|
|
142
|
+
* @param {String} [config.externalJwt] - JWT from external authority (eg Google)
|
|
143
|
+
* @param {String} [config.oidcOrigin] - Endpoint of authentication service
|
|
144
|
+
*/
|
|
145
|
+
constructor(config) {
|
|
146
|
+
this.kasKeys = {};
|
|
147
|
+
const clientConfig = { ...defaultClientConfig, ...config };
|
|
148
|
+
this.cryptoService = clientConfig.cryptoService;
|
|
149
|
+
this.dpopEnabled = !!(clientConfig.dpopEnabled || clientConfig.dpopKeys);
|
|
150
|
+
clientConfig.readerUrl && (this.readerUrl = clientConfig.readerUrl);
|
|
151
|
+
if (clientConfig.kasEndpoint) {
|
|
152
|
+
this.kasEndpoint = clientConfig.kasEndpoint;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// handle Deprecated `kasRewrapEndpoint` parameter
|
|
156
|
+
if (!clientConfig.keyRewrapEndpoint) {
|
|
157
|
+
throw new ConfigurationError('KAS definition not found');
|
|
158
|
+
}
|
|
159
|
+
this.kasEndpoint = clientConfig.keyRewrapEndpoint.replace(/\/rewrap$/, '');
|
|
160
|
+
}
|
|
161
|
+
this.kasEndpoint = rstrip(this.kasEndpoint, '/');
|
|
162
|
+
if (clientConfig.policyEndpoint) {
|
|
163
|
+
this.policyEndpoint = rstrip(clientConfig.policyEndpoint, '/');
|
|
164
|
+
}
|
|
165
|
+
else if (this.kasEndpoint.endsWith('/kas')) {
|
|
166
|
+
this.policyEndpoint = this.kasEndpoint.slice(0, -4);
|
|
167
|
+
}
|
|
168
|
+
const kasOrigin = new URL(this.kasEndpoint).origin;
|
|
169
|
+
if (clientConfig.allowedKases) {
|
|
170
|
+
this.allowedKases = new OriginAllowList(clientConfig.allowedKases, !!clientConfig.ignoreAllowList);
|
|
171
|
+
if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.allows(kasOrigin)) {
|
|
172
|
+
throw new ConfigurationError(`Invalid KAS endpoint [${this.kasEndpoint}]`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
if (!validateSecureUrl(this.kasEndpoint)) {
|
|
177
|
+
throw new ConfigurationError(`Invalid KAS endpoint [${this.kasEndpoint}]; to force, please list it among allowedKases`);
|
|
178
|
+
}
|
|
179
|
+
this.allowedKases = new OriginAllowList([kasOrigin], !!clientConfig.ignoreAllowList);
|
|
180
|
+
}
|
|
181
|
+
this.authProvider = config.authProvider;
|
|
182
|
+
this.clientConfig = clientConfig;
|
|
183
|
+
if (this.authProvider && isAppIdProviderCheck(this.authProvider)) {
|
|
184
|
+
this.eas = new EAS({
|
|
185
|
+
authProvider: this.authProvider,
|
|
186
|
+
endpoint: clientConfig.entityObjectEndpoint ?? `${clientConfig.easEndpoint}/api/entityobject`,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
this.clientId = clientConfig.clientId;
|
|
190
|
+
if (!this.authProvider) {
|
|
191
|
+
if (!clientConfig.clientId) {
|
|
192
|
+
throw new ConfigurationError('Client ID or custom AuthProvider must be defined');
|
|
193
|
+
}
|
|
194
|
+
//Are we exchanging a refreshToken for a bearer token (normal AuthCode browser auth flow)?
|
|
195
|
+
//If this is a browser context, we expect the caller to handle the initial
|
|
196
|
+
//browser-based OIDC login and authentication process against the OIDC endpoint using their chosen method,
|
|
197
|
+
//and provide us with a valid refresh token/clientId obtained from that process.
|
|
198
|
+
if (clientConfig.refreshToken) {
|
|
199
|
+
this.authProvider = new OIDCRefreshTokenProvider({
|
|
200
|
+
clientId: clientConfig.clientId,
|
|
201
|
+
refreshToken: clientConfig.refreshToken,
|
|
202
|
+
oidcOrigin: clientConfig.oidcOrigin,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else if (clientConfig.externalJwt) {
|
|
206
|
+
//Are we exchanging a JWT previously issued by a trusted external entity (e.g. Google) for a bearer token?
|
|
207
|
+
this.authProvider = new OIDCExternalJwtProvider({
|
|
208
|
+
clientId: clientConfig.clientId,
|
|
209
|
+
externalJwt: clientConfig.externalJwt,
|
|
210
|
+
oidcOrigin: clientConfig.oidcOrigin,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
this.dpopKeys = createSessionKeys({
|
|
215
|
+
authProvider: this.authProvider,
|
|
216
|
+
cryptoService: this.cryptoService,
|
|
217
|
+
dpopKeys: clientConfig.dpopKeys,
|
|
218
|
+
});
|
|
219
|
+
if (clientConfig.kasPublicKey) {
|
|
220
|
+
this.kasKeys[this.kasEndpoint] = Promise.resolve({
|
|
221
|
+
url: this.kasEndpoint,
|
|
222
|
+
algorithm: 'rsa:2048',
|
|
223
|
+
key: pemToCryptoPublicKey(clientConfig.kasPublicKey),
|
|
224
|
+
publicKey: clientConfig.kasPublicKey,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Encrypt plaintext into TDF ciphertext. One of the core operations of the Virtru SDK.
|
|
230
|
+
*
|
|
231
|
+
* @param scope dissem and attributes for constructing the policy
|
|
232
|
+
* @param source source object of unencrypted data
|
|
233
|
+
* @param [asHtml] If we should wrap the TDF data in a self-opening HTML wrapper. Defaults to false
|
|
234
|
+
* @param [autoconfigure] If we should use scope.attributes to configure KAOs
|
|
235
|
+
* @param [metadata] Additional non-secret data to store with the TDF
|
|
236
|
+
* @param [opts] Test only
|
|
237
|
+
* @param [mimeType] mime type of source. defaults to `unknown`
|
|
238
|
+
* @param [offline] Where to store the policy. Defaults to `false` - which results in `upsert` events to store/update a policy
|
|
239
|
+
* @param [windowSize] - segment size in bytes. Defaults to a a million bytes.
|
|
240
|
+
* @param [keyMiddleware] - function that handle keys
|
|
241
|
+
* @param [streamMiddleware] - function that handle stream
|
|
242
|
+
* @param [eo] - (deprecated) entity object
|
|
243
|
+
* @return a {@link https://nodejs.org/api/stream.html#stream_class_stream_readable|Readable} a new stream containing the TDF ciphertext
|
|
244
|
+
*/
|
|
245
|
+
async encrypt({ scope = { attributes: [], dissem: [] }, autoconfigure, source, asHtml = false, metadata, mimeType, offline = false, windowSize = DEFAULT_SEGMENT_SIZE, eo, keyMiddleware = defaultKeyMiddleware, streamMiddleware = async (stream) => stream, splitPlan, assertionConfigs = [], }) {
|
|
246
|
+
const dpopKeys = await this.dpopKeys;
|
|
247
|
+
const policyObject = asPolicy(scope);
|
|
248
|
+
validatePolicyObject(policyObject);
|
|
249
|
+
if (!splitPlan && autoconfigure) {
|
|
250
|
+
let avs = scope.attributeValues ?? [];
|
|
251
|
+
const fqns = scope.attributes
|
|
252
|
+
? scope.attributes.map((attribute) => typeof attribute === 'string' ? attribute : attribute.attribute)
|
|
253
|
+
: [];
|
|
254
|
+
if (!avs.length && fqns.length) {
|
|
255
|
+
// Hydrate avs from policy endpoint givnen the fqns
|
|
256
|
+
if (!this.policyEndpoint) {
|
|
257
|
+
throw new ConfigurationError('policyEndpoint not set in TDF3 Client constructor');
|
|
258
|
+
}
|
|
259
|
+
avs = await attributeFQNsAsValues(this.policyEndpoint, this.authProvider, ...fqns);
|
|
260
|
+
}
|
|
261
|
+
else if (scope.attributeValues) {
|
|
262
|
+
avs = scope.attributeValues;
|
|
263
|
+
if (!scope.attributes) {
|
|
264
|
+
scope.attributes = avs.map(({ fqn }) => fqn);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (avs.length != scope.attributes?.length ||
|
|
268
|
+
!avs.map(({ fqn }) => fqn).every((a) => fqns.indexOf(a) >= 0)) {
|
|
269
|
+
throw new ConfigurationError(`Attribute mismatch between [${fqns}] and explicit values ${JSON.stringify(avs.map(({ fqn }) => fqn))}`);
|
|
270
|
+
}
|
|
271
|
+
const detailedPlan = plan(avs);
|
|
272
|
+
splitPlan = detailedPlan.map((kat) => {
|
|
273
|
+
const { kas, sid } = kat;
|
|
274
|
+
if (kas?.publicKey?.cached?.keys && !(kas.uri in this.kasKeys)) {
|
|
275
|
+
const keys = kas.publicKey.cached.keys.filter(({ alg }) => alg == 'KAS_PUBLIC_KEY_ALG_ENUM_RSA_2048');
|
|
276
|
+
if (keys?.length) {
|
|
277
|
+
const key = keys[0];
|
|
278
|
+
this.kasKeys[kas.uri] = Promise.resolve({
|
|
279
|
+
key: pemToCryptoPublicKey(key.pem),
|
|
280
|
+
publicKey: key.pem,
|
|
281
|
+
url: kas.uri,
|
|
282
|
+
algorithm: 'rsa:2048',
|
|
283
|
+
kid: key.kid,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return { kas: kas.uri, sid };
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
// TODO: Refactor underlying builder to remove some of this unnecessary config.
|
|
291
|
+
const byteLimit = asHtml ? HTML_BYTE_LIMIT : GLOBAL_BYTE_LIMIT;
|
|
292
|
+
const encryptionInformation = new SplitKey(new AesGcmCipher(this.cryptoService));
|
|
293
|
+
let attributeSet;
|
|
294
|
+
let entity;
|
|
295
|
+
if (eo) {
|
|
296
|
+
entity = eo;
|
|
297
|
+
const s = new AttributeSet();
|
|
298
|
+
eo.attributes.forEach((attr) => s.addJwtAttribute(attr));
|
|
299
|
+
attributeSet = s;
|
|
300
|
+
}
|
|
301
|
+
const splits = splitPlan?.length ? splitPlan : [{ kas: this.kasEndpoint }];
|
|
302
|
+
encryptionInformation.keyAccess = await Promise.all(splits.map(async ({ kas, sid }) => {
|
|
303
|
+
if (!(kas in this.kasKeys)) {
|
|
304
|
+
this.kasKeys[kas] = fetchKasPublicKey(kas);
|
|
305
|
+
}
|
|
306
|
+
const kasPublicKey = await this.kasKeys[kas];
|
|
307
|
+
return buildKeyAccess({
|
|
308
|
+
attributeSet,
|
|
309
|
+
type: offline ? 'wrapped' : 'remote',
|
|
310
|
+
url: kasPublicKey.url,
|
|
311
|
+
kid: kasPublicKey.kid,
|
|
312
|
+
publicKey: kasPublicKey.publicKey,
|
|
313
|
+
metadata,
|
|
314
|
+
sid,
|
|
315
|
+
});
|
|
316
|
+
}));
|
|
317
|
+
const { keyForEncryption, keyForManifest } = await keyMiddleware();
|
|
318
|
+
const ecfg = {
|
|
319
|
+
allowList: this.allowedKases,
|
|
320
|
+
attributeSet,
|
|
321
|
+
byteLimit,
|
|
322
|
+
cryptoService: this.cryptoService,
|
|
323
|
+
dpopKeys,
|
|
324
|
+
encryptionInformation,
|
|
325
|
+
entity,
|
|
326
|
+
segmentSizeDefault: windowSize,
|
|
327
|
+
integrityAlgorithm: 'HS256',
|
|
328
|
+
segmentIntegrityAlgorithm: 'GMAC',
|
|
329
|
+
contentStream: source,
|
|
330
|
+
mimeType,
|
|
331
|
+
policy: policyObject,
|
|
332
|
+
authProvider: this.authProvider,
|
|
333
|
+
progressHandler: this.clientConfig.progressHandler,
|
|
334
|
+
keyForEncryption,
|
|
335
|
+
keyForManifest,
|
|
336
|
+
assertionConfigs,
|
|
337
|
+
};
|
|
338
|
+
const stream = await streamMiddleware(await writeStream(ecfg));
|
|
339
|
+
if (!asHtml) {
|
|
340
|
+
return stream;
|
|
341
|
+
}
|
|
342
|
+
// Wrap if it's html.
|
|
343
|
+
if (!stream.manifest) {
|
|
344
|
+
throw new Error('internal: missing manifest in encrypt function');
|
|
345
|
+
}
|
|
346
|
+
const htmlBuf = wrapHtml(await stream.toBuffer(), stream.manifest, this.readerUrl ?? '');
|
|
347
|
+
return new DecoratedReadableStream({
|
|
348
|
+
pull(controller) {
|
|
349
|
+
controller.enqueue(htmlBuf);
|
|
350
|
+
controller.close();
|
|
351
|
+
},
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Decrypt TDF ciphertext into plaintext. One of the core operations of the Virtru SDK.
|
|
356
|
+
*
|
|
357
|
+
* @param params keyMiddleware fucntion to process key
|
|
358
|
+
* @param params streamMiddleware fucntion to process streamMiddleware
|
|
359
|
+
* @param params.source A data stream object, one of remote, stream, buffer, etc. types.
|
|
360
|
+
* @param params.eo Optional entity object (legacy AuthZ)
|
|
361
|
+
* @param params.assertionVerificationKeys Optional verification keys for assertions.
|
|
362
|
+
* @return a {@link https://nodejs.org/api/stream.html#stream_class_stream_readable|Readable} stream containing the decrypted plaintext.
|
|
363
|
+
* @see DecryptParamsBuilder
|
|
364
|
+
*/
|
|
365
|
+
async decrypt({ eo, source, keyMiddleware = async (key) => key, streamMiddleware = async (stream) => stream, assertionVerificationKeys, noVerifyAssertions, }) {
|
|
366
|
+
const dpopKeys = await this.dpopKeys;
|
|
367
|
+
let entityObject;
|
|
368
|
+
if (this.eas || eo) {
|
|
369
|
+
const sessionPublicKey = await cryptoPublicToPem(dpopKeys.publicKey);
|
|
370
|
+
if (eo && eo.publicKey == sessionPublicKey) {
|
|
371
|
+
entityObject = eo;
|
|
372
|
+
}
|
|
373
|
+
else if (this.eas) {
|
|
374
|
+
entityObject = await this.eas.fetchEntityObject({
|
|
375
|
+
publicKey: sessionPublicKey,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (!this.authProvider) {
|
|
380
|
+
throw new ConfigurationError('AuthProvider missing');
|
|
381
|
+
}
|
|
382
|
+
const chunker = await makeChunkable(source);
|
|
383
|
+
// Await in order to catch any errors from this call.
|
|
384
|
+
// TODO: Write error event to stream and don't await.
|
|
385
|
+
return await streamMiddleware(await readStream({
|
|
386
|
+
allowList: this.allowedKases,
|
|
387
|
+
authProvider: this.authProvider,
|
|
388
|
+
chunker,
|
|
389
|
+
cryptoService: this.cryptoService,
|
|
390
|
+
dpopKeys,
|
|
391
|
+
entity: entityObject,
|
|
392
|
+
fileStreamServiceWorker: this.clientConfig.fileStreamServiceWorker,
|
|
393
|
+
keyMiddleware,
|
|
394
|
+
progressHandler: this.clientConfig.progressHandler,
|
|
395
|
+
assertionVerificationKeys,
|
|
396
|
+
noVerifyAssertions,
|
|
397
|
+
}));
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Get the unique policyId associated with TDF ciphertext. Useful for managing authorization policies of encrypted data.
|
|
401
|
+
* <br/><br/>
|
|
402
|
+
* The policyId is embedded in the ciphertext so this is a local operation.
|
|
403
|
+
*
|
|
404
|
+
* @param {object} source - Required. TDF data stream,
|
|
405
|
+
* generated using {@link DecryptParamsBuilder#build|DecryptParamsBuilder's build()}.
|
|
406
|
+
* @return {string} - the unique policyId, which can be used for tracking purposes or policy management operations.
|
|
407
|
+
* @see DecryptParamsBuilder
|
|
408
|
+
*/
|
|
409
|
+
async getPolicyId({ source }) {
|
|
410
|
+
const chunker = await makeChunkable(source);
|
|
411
|
+
const zipHelper = new ZipReader(chunker);
|
|
412
|
+
const centralDirectory = await zipHelper.getCentralDirectory();
|
|
413
|
+
const manifest = await zipHelper.getManifest(centralDirectory, '0.manifest.json');
|
|
414
|
+
const policyJson = base64.decode(manifest.encryptionInformation.policy);
|
|
415
|
+
return JSON.parse(policyJson).uuid;
|
|
416
|
+
}
|
|
417
|
+
async loadTDFStream({ source }) {
|
|
418
|
+
const chunker = await makeChunkable(source);
|
|
419
|
+
return loadTDFStream(chunker);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
export { AppIdAuthProvider, DecryptParamsBuilder, EncryptParamsBuilder, HttpRequest, fromDataSource, withHeaders, };
|
|
423
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZGYzL3NyYy9jbGllbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQixPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsY0FBYyxFQUNkLGNBQWMsRUFDZCxvQkFBb0IsRUFFcEIsYUFBYSxJQUFJLG9CQUFvQixHQUN0QyxNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsY0FBYyxFQUVkLGlCQUFpQixFQUNqQixhQUFhLEVBQ2IsVUFBVSxFQUNWLG9CQUFvQixFQUNwQixVQUFVLEVBQ1YsUUFBUSxFQUNSLFdBQVcsR0FDWixNQUFNLFdBQVcsQ0FBQztBQUNuQixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUMzRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUV6RixPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLFdBQVcsRUFDWCxXQUFXLEdBQ1osTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEdBQUcsTUFBTSwwQkFBMEIsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLG9CQUFvQixFQUNwQixNQUFNLEVBQ04saUJBQWlCLEdBQ2xCLE1BQU0sdUJBQXVCLENBQUM7QUFXL0IsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFdkUsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixvQkFBb0IsRUFFcEIsb0JBQW9CLEdBQ3JCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBb0IsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDM0Us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
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AttributeValidationError } from '../../../src/errors.js';
|
|
2
|
+
const sageGetMatch = (match) => (match ? match[0] : null);
|
|
3
|
+
export const ATTR_NAME_PROP_NAME = 'attr';
|
|
4
|
+
export const ATTR_VALUE_PROP_NAME = 'value';
|
|
5
|
+
// Validate attribute url protocol starts with `http://` or `https://`
|
|
6
|
+
const SCHEME = '(https?://)';
|
|
7
|
+
// validate url host be like `localhost:4000`
|
|
8
|
+
const HOST_PORT = '([a-z0-9][a-z0-9]{1,}:[0-9]{1,4})';
|
|
9
|
+
// validate url host be like `www.example.com`
|
|
10
|
+
const WWW_HOST = '([a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z]{2,}';
|
|
11
|
+
// validate url host be like `127.0.0.1:4000`
|
|
12
|
+
const IP_HOST_PORT = '([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}:[0-9]{1,4})';
|
|
13
|
+
// validate host is one of those above
|
|
14
|
+
const HOST = `(${HOST_PORT}|${WWW_HOST}|${IP_HOST_PORT})`;
|
|
15
|
+
// validate attr name be like `/attr/<attr_name>`
|
|
16
|
+
export const ATTR_NAME = `(/${ATTR_NAME_PROP_NAME}/[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]?)`;
|
|
17
|
+
// validate value pattern
|
|
18
|
+
export const ATTR_VALUE = `(/${ATTR_VALUE_PROP_NAME}/[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]?)`;
|
|
19
|
+
// validate attribute authority e.g. https://example.com
|
|
20
|
+
const ATTR_AUTHORITY_PATTERN = `(${SCHEME}${HOST})`;
|
|
21
|
+
// validate attribute namespace e.g. https://example.com/attr/someattribute
|
|
22
|
+
const ATTR_NAMESPACE_PATTERN = `(${ATTR_AUTHORITY_PATTERN}${ATTR_NAME})`;
|
|
23
|
+
// validate whole attribute e.g. https://example.com/attr/someattribute/value/somevalue
|
|
24
|
+
export const ATTR_ATTRIBUTE_PATTERN = `^(${ATTR_NAMESPACE_PATTERN}${ATTR_VALUE})$`;
|
|
25
|
+
export const validateAttributeObject = (attr) => {
|
|
26
|
+
const isObject = typeof attr === 'object';
|
|
27
|
+
if (!isObject) {
|
|
28
|
+
throw new AttributeValidationError(`attribute should be an object`, attr);
|
|
29
|
+
}
|
|
30
|
+
const { attribute } = attr;
|
|
31
|
+
const isString = typeof attribute === 'string';
|
|
32
|
+
if (!isString) {
|
|
33
|
+
throw new AttributeValidationError(`attribute prop should be a string`, attr);
|
|
34
|
+
}
|
|
35
|
+
return validateAttribute(attribute);
|
|
36
|
+
};
|
|
37
|
+
export function validateAttribute(attribute) {
|
|
38
|
+
if (!attribute.match(ATTR_ATTRIBUTE_PATTERN)) {
|
|
39
|
+
throw new AttributeValidationError(`attribute is in invalid format [${attribute}]`, attribute);
|
|
40
|
+
}
|
|
41
|
+
const ATTR_NAME_PREFIX = `/${ATTR_NAME_PROP_NAME}/`;
|
|
42
|
+
const ATTR_VALUE_PREFIX = `/${ATTR_VALUE_PROP_NAME}/`;
|
|
43
|
+
const attrNameMatch = sageGetMatch(attribute.match(ATTR_NAME));
|
|
44
|
+
const attrValueMatch = sageGetMatch(attribute.match(ATTR_VALUE));
|
|
45
|
+
if (!attrNameMatch) {
|
|
46
|
+
throw new AttributeValidationError(`attribute name matching error`, attribute);
|
|
47
|
+
}
|
|
48
|
+
if (!attrValueMatch) {
|
|
49
|
+
throw new AttributeValidationError(`attribute value matching error`, attribute);
|
|
50
|
+
}
|
|
51
|
+
const attributeName = attrNameMatch.slice(ATTR_NAME_PREFIX.length);
|
|
52
|
+
const attributeValue = attrValueMatch.slice(ATTR_VALUE_PREFIX.length);
|
|
53
|
+
if (attributeName === attributeValue) {
|
|
54
|
+
throw new AttributeValidationError(`attribute name should be unique with its value`, attribute);
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3RkZjMvc3JjL2NsaWVudC92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRWxFLE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBOEIsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFbkYsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsTUFBTSxDQUFDO0FBQzFDLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLE9BQU8sQ0FBQztBQUU1QyxzRUFBc0U7QUFDdEUsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDO0FBRTdCLDZDQUE2QztBQUM3QyxNQUFNLFNBQVMsR0FBRyxtQ0FBbUMsQ0FBQztBQUV0RCw4Q0FBOEM7QUFDOUMsTUFBTSxRQUFRLEdBQUcsZ0RBQWdELENBQUM7QUFFbEUsNkNBQTZDO0FBQzdDLE1BQU0sWUFBWSxHQUFHLGdFQUFnRSxDQUFDO0FBRXRGLHNDQUFzQztBQUN0QyxNQUFNLElBQUksR0FBRyxJQUFJLFNBQVMsSUFBSSxRQUFRLElBQUksWUFBWSxHQUFHLENBQUM7QUFFMUQsa0RBQWtEO0FBQ2xELE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxLQUFLLG1CQUFtQix3Q0FBd0MsQ0FBQztBQUUxRix5QkFBeUI7QUFDekIsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLEtBQUssb0JBQW9CLHdDQUF3QyxDQUFDO0FBRTVGLHlEQUF5RDtBQUN6RCxNQUFNLHNCQUFzQixHQUFHLElBQUksTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDO0FBRXBELDJFQUEyRTtBQUMzRSxNQUFNLHNCQUFzQixHQUFHLElBQUksc0JBQXNCLEdBQUcsU0FBUyxHQUFHLENBQUM7QUFFekUsdUZBQXVGO0FBQ3ZGLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLEtBQUssc0JBQXNCLEdBQUcsVUFBVSxJQUFJLENBQUM7QUFFbkYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxJQUFhLEVBQWdCLEVBQUU7SUFDckUsTUFBTSxRQUFRLEdBQUcsT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDO0lBQzFDLElBQUksQ0FBQyxRQUFRLEVBQUU7UUFDYixNQUFNLElBQUksd0JBQXdCLENBQUMsK0JBQStCLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDM0U7SUFFRCxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBK0IsQ0FBQztJQUN0RCxNQUFNLFFBQVEsR0FBRyxPQUFPLFNBQVMsS0FBSyxRQUFRLENBQUM7SUFDL0MsSUFBSSxDQUFDLFFBQVEsRUFBRTtRQUNiLE1BQU0sSUFBSSx3QkFBd0IsQ0FBQyxtQ0FBbUMsRUFBRSxJQUFJLENBQUMsQ0FBQztLQUMvRTtJQUVELE9BQU8saUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDdEMsQ0FBQyxDQUFDO0FBRUYsTUFBTSxVQUFVLGlCQUFpQixDQUFDLFNBQWlCO0lBQ2pELElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLEVBQUU7UUFDNUMsTUFBTSxJQUFJLHdCQUF3QixDQUFDLG1DQUFtQyxTQUFTLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztLQUNoRztJQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxtQkFBbUIsR0FBRyxDQUFDO0lBQ3BELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxvQkFBb0IsR0FBRyxDQUFDO0lBQ3RELE1BQU0sYUFBYSxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDL0QsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUVqRSxJQUFJLENBQUMsYUFBYSxFQUFFO1FBQ2xCLE1BQU0sSUFBSSx3QkFBd0IsQ0FBQywrQkFBK0IsRUFBRSxTQUFTLENBQUMsQ0FBQztLQUNoRjtJQUVELElBQUksQ0FBQyxjQUFjLEVBQUU7UUFDbkIsTUFBTSxJQUFJLHdCQUF3QixDQUFDLGdDQUFnQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0tBQ2pGO0lBRUQsTUFBTSxhQUFhLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuRSxNQUFNLGNBQWMsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXRFLElBQUksYUFBYSxLQUFLLGNBQWMsRUFBRTtRQUNwQyxNQUFNLElBQUksd0JBQXdCLENBQUMsZ0RBQWdELEVBQUUsU0FBUyxDQUFDLENBQUM7S0FDakc7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMifQ==
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { base64 } from '../../../src/encodings/index.js';
|
|
2
|
+
import { rsaPkcs1Sha256 } from './index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Validates a specified key size
|
|
5
|
+
* @param size in bits requested
|
|
6
|
+
* @param minSize in bits allowed
|
|
7
|
+
*/
|
|
8
|
+
export const isValidAsymmetricKeySize = (size, minSize) => {
|
|
9
|
+
// No size specified is fine because the minSize will be used
|
|
10
|
+
if (size === undefined) {
|
|
11
|
+
return !!minSize;
|
|
12
|
+
}
|
|
13
|
+
if (typeof size !== 'number' || (minSize && size < minSize)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Format a base64 string representation of a key file
|
|
20
|
+
* in PEM PKCS#8 format by adding a header and footer
|
|
21
|
+
* and new lines.
|
|
22
|
+
*
|
|
23
|
+
* The PEM spec says to use <CR><LF> (\r\n) per
|
|
24
|
+
* https://tools.ietf.org/html/rfc1421#section-4.3.2.2, but
|
|
25
|
+
* many implementations use just \n, so this function
|
|
26
|
+
* follows the convention over the spec.
|
|
27
|
+
*
|
|
28
|
+
* @param base64KeyString input
|
|
29
|
+
* @param label header and footer label that identifies key type
|
|
30
|
+
* @return formatted output
|
|
31
|
+
*/
|
|
32
|
+
export const formatAsPem = (bytes, label) => {
|
|
33
|
+
let pemCert = `-----BEGIN ${label}-----\n`;
|
|
34
|
+
let nextIndex = 0;
|
|
35
|
+
const base64KeyString = base64.encodeArrayBuffer(bytes);
|
|
36
|
+
while (nextIndex < base64KeyString.length) {
|
|
37
|
+
if (nextIndex + 64 <= base64KeyString.length) {
|
|
38
|
+
pemCert += `${base64KeyString.substr(nextIndex, 64)}\n`;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
pemCert += `${base64KeyString.substr(nextIndex)}\n`;
|
|
42
|
+
}
|
|
43
|
+
nextIndex += 64;
|
|
44
|
+
}
|
|
45
|
+
pemCert += `-----END ${label}-----\n`;
|
|
46
|
+
return pemCert;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Remove PEM formatting (new line characters and headers / footers)
|
|
50
|
+
* from a PEM string
|
|
51
|
+
*
|
|
52
|
+
* @param input - PEM formatted string
|
|
53
|
+
* @return String with formatting removed
|
|
54
|
+
*/
|
|
55
|
+
export const removePemFormatting = (input) => {
|
|
56
|
+
if (typeof input !== 'string') {
|
|
57
|
+
console.error('Not a pem string', input);
|
|
58
|
+
return input;
|
|
59
|
+
}
|
|
60
|
+
const oneLiner = input.replace(/[\n\r]/g, '');
|
|
61
|
+
// https://www.rfc-editor.org/rfc/rfc7468#section-2
|
|
62
|
+
return oneLiner.replace(/-----(?:BEGIN|END)\s(?:RSA\s)?(?:PUBLIC|PRIVATE|CERTIFICATE)\sKEY-----/g, '');
|
|
63
|
+
};
|
|
64
|
+
const PEMRE = /-----BEGIN\s((?:RSA\s)?(?:PUBLIC\sKEY|PRIVATE\sKEY|CERTIFICATE))-----[\s0-9A-Za-z+/=]+-----END\s\1-----/;
|
|
65
|
+
export const isPemKeyPair = (i) => {
|
|
66
|
+
const { privateKey, publicKey } = i;
|
|
67
|
+
if (typeof privateKey !== 'string' || typeof publicKey !== 'string') {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const privateMatch = PEMRE.exec(privateKey);
|
|
71
|
+
if (!privateMatch || !privateMatch[1] || privateMatch[1].indexOf('PRIVATE KEY') < 0) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const publicMatch = PEMRE.exec(publicKey);
|
|
75
|
+
if (!publicMatch || !publicMatch[1] || publicMatch[1].indexOf('PRIVATE') >= 0) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
};
|
|
80
|
+
export const isCryptoKeyPair = (i) => {
|
|
81
|
+
const { privateKey, publicKey } = i;
|
|
82
|
+
if (typeof privateKey !== 'object' || typeof publicKey !== 'object') {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (!(privateKey instanceof CryptoKey) || !(publicKey instanceof CryptoKey)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return privateKey.type === 'private' && publicKey.type === 'public';
|
|
89
|
+
};
|
|
90
|
+
export const toCryptoKeyPair = async (input) => {
|
|
91
|
+
if (isCryptoKeyPair(input)) {
|
|
92
|
+
return input;
|
|
93
|
+
}
|
|
94
|
+
if (!isPemKeyPair(input)) {
|
|
95
|
+
throw new Error('internal: generated invalid keypair');
|
|
96
|
+
}
|
|
97
|
+
const k = [input.publicKey, input.privateKey]
|
|
98
|
+
.map(removePemFormatting)
|
|
99
|
+
.map((e) => base64.decodeArrayBuffer(e));
|
|
100
|
+
const algorithm = rsaPkcs1Sha256();
|
|
101
|
+
const [publicKey, privateKey] = await Promise.all([
|
|
102
|
+
crypto.subtle.importKey('spki', k[0], algorithm, true, ['verify']),
|
|
103
|
+
crypto.subtle.importKey('pkcs8', k[1], algorithm, true, ['sign']),
|
|
104
|
+
]);
|
|
105
|
+
return { privateKey, publicKey };
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J5cHRvLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGRmMy9zcmMvY3J5cHRvL2NyeXB0by11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFekQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUU1Qzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxJQUF3QixFQUFFLE9BQWdCLEVBQVcsRUFBRTtJQUM5Riw2REFBNkQ7SUFDN0QsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFO1FBQ3RCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQztLQUNsQjtJQUVELElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsRUFBRTtRQUMzRCxPQUFPLEtBQUssQ0FBQztLQUNkO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLENBQUMsS0FBa0IsRUFBRSxLQUFhLEVBQVUsRUFBRTtJQUN2RSxJQUFJLE9BQU8sR0FBRyxjQUFjLEtBQUssU0FBUyxDQUFDO0lBQzNDLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNsQixNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEQsT0FBTyxTQUFTLEdBQUcsZUFBZSxDQUFDLE1BQU0sRUFBRTtRQUN6QyxJQUFJLFNBQVMsR0FBRyxFQUFFLElBQUksZUFBZSxDQUFDLE1BQU0sRUFBRTtZQUM1QyxPQUFPLElBQUksR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDO1NBQ3pEO2FB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
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The minimum acceptable asymetric key size, currently 2^11.
|
|
3
|
+
*/
|
|
4
|
+
export const MIN_ASYMMETRIC_KEY_SIZE_BITS = 2048;
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjbGFyYXRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGRmMy9zcmMvY3J5cHRvL2RlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFzQkE7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBRyxJQUFJLENBQUMifQ==
|