@atproto/jwk
Version:
A library for working with JSON Web Keys (JWKs) in TypeScript. This is meant to be extended by environment-specific libraries like @atproto/jwk-jose.
112 lines • 4.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.jwkPubSchema = exports.jwkValidator = exports.jwkSchema = exports.jwkUnknownKeySchema = exports.jwkSymKeySchema = exports.jwkOkpKeySchema = exports.jwkEcSecp256k1KeySchema = exports.jwkEcKeySchema = exports.jwkRsaKeySchema = exports.jwkBaseSchema = exports.keyUsageSchema = void 0;
const zod_1 = require("zod");
exports.keyUsageSchema = zod_1.z.enum([
'sign',
'verify',
'encrypt',
'decrypt',
'wrapKey',
'unwrapKey',
'deriveKey',
'deriveBits',
]);
/**
* The "use" and "key_ops" JWK members SHOULD NOT be used together;
* however, if both are used, the information they convey MUST be
* consistent. Applications should specify which of these members they
* use, if either is to be used by the application.
*
* @todo Actually check that "use" and "key_ops" are consistent when both are present.
* @see {@link https://datatracker.ietf.org/doc/html/rfc7517#section-4.3}
*/
exports.jwkBaseSchema = zod_1.z.object({
kty: zod_1.z.string().min(1),
alg: zod_1.z.string().min(1).optional(),
kid: zod_1.z.string().min(1).optional(),
ext: zod_1.z.boolean().optional(),
use: zod_1.z.enum(['sig', 'enc']).optional(),
key_ops: zod_1.z.array(exports.keyUsageSchema).optional(),
x5c: zod_1.z.array(zod_1.z.string()).optional(), // X.509 Certificate Chain
x5t: zod_1.z.string().min(1).optional(), // X.509 Certificate SHA-1 Thumbprint
'x5t#S256': zod_1.z.string().min(1).optional(), // X.509 Certificate SHA-256 Thumbprint
x5u: zod_1.z.string().url().optional(), // X.509 URL
});
/**
* @todo: properly implement this
*/
exports.jwkRsaKeySchema = exports.jwkBaseSchema.extend({
kty: zod_1.z.literal('RSA'),
alg: zod_1.z
.enum(['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512'])
.optional(),
n: zod_1.z.string().min(1), // Modulus
e: zod_1.z.string().min(1), // Exponent
d: zod_1.z.string().min(1).optional(), // Private Exponent
p: zod_1.z.string().min(1).optional(), // First Prime Factor
q: zod_1.z.string().min(1).optional(), // Second Prime Factor
dp: zod_1.z.string().min(1).optional(), // First Factor CRT Exponent
dq: zod_1.z.string().min(1).optional(), // Second Factor CRT Exponent
qi: zod_1.z.string().min(1).optional(), // First CRT Coefficient
oth: zod_1.z
.array(zod_1.z.object({
r: zod_1.z.string().optional(),
d: zod_1.z.string().optional(),
t: zod_1.z.string().optional(),
}))
.nonempty()
.optional(), // Other Primes Info
});
exports.jwkEcKeySchema = exports.jwkBaseSchema.extend({
kty: zod_1.z.literal('EC'),
alg: zod_1.z.enum(['ES256', 'ES384', 'ES512']).optional(),
crv: zod_1.z.enum(['P-256', 'P-384', 'P-521']),
x: zod_1.z.string().min(1),
y: zod_1.z.string().min(1),
d: zod_1.z.string().min(1).optional(), // ECC Private Key
});
exports.jwkEcSecp256k1KeySchema = exports.jwkBaseSchema.extend({
kty: zod_1.z.literal('EC'),
alg: zod_1.z.enum(['ES256K']).optional(),
crv: zod_1.z.enum(['secp256k1']),
x: zod_1.z.string().min(1),
y: zod_1.z.string().min(1),
d: zod_1.z.string().min(1).optional(), // ECC Private Key
});
exports.jwkOkpKeySchema = exports.jwkBaseSchema.extend({
kty: zod_1.z.literal('OKP'),
alg: zod_1.z.enum(['EdDSA']).optional(),
crv: zod_1.z.enum(['Ed25519', 'Ed448']),
x: zod_1.z.string().min(1),
d: zod_1.z.string().min(1).optional(), // ECC Private Key
});
exports.jwkSymKeySchema = exports.jwkBaseSchema.extend({
kty: zod_1.z.literal('oct'), // Octet Sequence (used to represent symmetric keys)
alg: zod_1.z.enum(['HS256', 'HS384', 'HS512']).optional(),
k: zod_1.z.string(), // Key Value (base64url encoded)
});
exports.jwkUnknownKeySchema = exports.jwkBaseSchema.extend({
kty: zod_1.z
.string()
.refine((v) => v !== 'RSA' && v !== 'EC' && v !== 'OKP' && v !== 'oct'),
});
exports.jwkSchema = zod_1.z.union([
exports.jwkUnknownKeySchema,
exports.jwkRsaKeySchema,
exports.jwkEcKeySchema,
exports.jwkEcSecp256k1KeySchema,
exports.jwkOkpKeySchema,
exports.jwkSymKeySchema,
]);
exports.jwkValidator = exports.jwkSchema
.refine((k) => k.use != null || k.key_ops != null, 'use or key_ops required')
.refine((k) => !k.use ||
!k.key_ops ||
k.key_ops.every((o) => k.use === 'sig'
? o === 'sign' || o === 'verify'
: o === 'encrypt' || o === 'decrypt'), 'use and key_ops must be consistent');
exports.jwkPubSchema = exports.jwkValidator
.refine((k) => k.kid != null, 'kid is required')
.refine((k) => !('k' in k) && !('d' in k), 'private key not allowed');
//# sourceMappingURL=jwk.js.map