OpenPrinting / libcups

OpenPrinting CUPS Library Sources
https://openprinting.github.io/cups/cups3.html
Apache License 2.0
27 stars 15 forks source link

JWT API for reading/writing JSON Web Tickets #50

Closed michaelrsweet closed 1 year ago

michaelrsweet commented 1 year ago

Add a JWT API for reading and writing JSON Web Tokens (JWT), JSON Web Encryption (JWE), and JSON Web Signatures (JWS).

Relevant standards:

michaelrsweet commented 1 year ago

Preliminary API (work-in-progress):

#define CUPS_JWT_AUD "aud" // JWT audience claim
#define CUPS_JWT_EXP "exp" // JWT expiration date/time claim
#define CUPS_JWT_IAT "iat" // JWT issued at date/time claim
#define CUPS_JWT_ISS "iss" // JWT issuer claim
#define CUPS_JWT_JTI "jti" // JWT unique identifier claim
#define CUPS_JWT_NBF "nbf" // JWT not before date/time claim
#define CUPS_JWT_SUB "sub" // JWT subject claim

typedef struct _cups_jwt_s cups_jwt_t; // JSON Web Token

extern void cupsJWTDelete(cups_jwt_t *jwt) _CUPS_PUBLIC;
extern char *cupsJWTExport(cups_jwt_t *jwt) _CUPS_PUBLIC;
extern cups_jwt_t *cupsJWTImport(const char *token) _CUPS_PUBLIC;
extern cups_jwt_t *cupsJWTNew(const char *type, const char *algorithm, cups_json_t *keys, size_t num_claims, cups_option_t *claims) _CUPS_PUBLIC;
michaelrsweet commented 1 year ago

Latest API:

//
// Constants...
//

#define CUPS_JWT_AUD    "aud"       // JWT audience claim
#define CUPS_JWT_EXP    "exp"       // JWT expiration date/time claim
#define CUPS_JWT_IAT    "iat"       // JWT issued at date/time claim
#define CUPS_JWT_ISS    "iss"       // JWT issuer claim (authorization server)
#define CUPS_JWT_JTI    "jti"       // JWT unique identifier claim
#define CUPS_JWT_NAME   "name"      // OpenID display name
#define CUPS_JWT_NBF    "nbf"       // JWT not before date/time claim
#define CUPS_JWT_SUB    "sub"       // JWT subject claim (username/ID)

//
// Types...
//

typedef enum cups_jwa_e         // JSON Web Algorithms
{
  CUPS_JWA_NONE,            // No algorithm
  CUPS_JWA_HS256,           // HMAC using SHA-256
  CUPS_JWA_HS384,           // HMAC using SHA-384
  CUPS_JWA_HS512,           // HMAC using SHA-512
  CUPS_JWA_RS256,           // RSASSA-PKCS1-v1_5 using SHA-256
  CUPS_JWA_RS384,           // RSASSA-PKCS1-v1_5 using SHA-384
  CUPS_JWA_RS512,           // RSASSA-PKCS1-v1_5 using SHA-512
  CUPS_JWA_ES256,           // ECDSA using P-256 and SHA-256
  CUPS_JWA_ES384,           // ECDSA using P-384 and SHA-384
  CUPS_JWA_ES512,           // ECDSA using P-521 and SHA-512
  CUPS_JWA_MAX              // @private@ Maximum JWA value
} cups_jwa_t;

typedef struct _cups_jwt_s cups_jwt_t;  // JSON Web Token

//
// Functions...
//

extern void     cupsJWTDelete(cups_jwt_t *jwt) _CUPS_PUBLIC;
extern char     *cupsJWTExportString(cups_jwt_t *jwt) _CUPS_PUBLIC;
extern cups_jwa_t   cupsJWTGetAlgorithm(cups_jwt_t *jwt) _CUPS_PUBLIC;
extern double       cupsJWTGetClaimNumber(cups_jwt_t *jwt, const char *claim) _CUPS_PUBLIC;
extern const char   *cupsJWTGetClaimString(cups_jwt_t *jwt, const char *claim) _CUPS_PUBLIC;
extern cups_jtype_t cupsJWTGetClaimType(cups_jwt_t *jwt, const char *claim) _CUPS_PUBLIC;
extern cups_json_t  *cupsJWTGetClaimValue(cups_jwt_t *jwt, const char *claim) _CUPS_PUBLIC;
extern cups_json_t  *cupsJWTGetClaims(cups_jwt_t *jwt) _CUPS_PUBLIC;
extern bool     cupsJWTHasValidSignature(cups_jwt_t *jwt, cups_json_t *keys) _CUPS_PUBLIC;
extern cups_jwt_t   *cupsJWTImportString(const char *token) _CUPS_PUBLIC;
extern cups_jwt_t   *cupsJWTNew(const char *type) _CUPS_PUBLIC;
extern void     cupsJWTSetClaimNumber(cups_jwt_t *jwt, const char *claim, double value) _CUPS_PUBLIC;
extern void     cupsJWTSetClaimString(cups_jwt_t *jwt, const char *claim, const char *value) _CUPS_PUBLIC;
extern void     cupsJWTSetClaimValue(cups_jwt_t *jwt, const char *claim, cups_json_t *value) _CUPS_PUBLIC;
extern bool     cupsJWTSign(cups_jwt_t *jwt, cups_jwa_t alg, cups_json_t *keys) _CUPS_PUBLIC;
michaelrsweet commented 1 year ago

Todo:

michaelrsweet commented 1 year ago

Still working on ECDSA support - the code is there but currently the unit tests are failing with the JWS examples.

Also want to provide reliable JWK generation.

michaelrsweet commented 1 year ago

Looks like everything is working as needed. New APIs for generating private and public JSON Web Keys:

extern cups_json_t  *cupsJWTMakePrivateKey(cups_jwa_t alg) _CUPS_PUBLIC;
extern cups_json_t  *cupsJWTMakePublicKey(cups_json_t *jwk) _CUPS_PUBLIC;