Third-party access token validation

There is a new API that is exposed in the SDK for 14.0. This would be usable from any server process, and would leverage the trusted OIDC providers configured in idpcat.nsf to validate access tokens.

/* SECValidateAccessToken
 *
 * Validates a signed JWT access token that was generated by a trusted OIDC provider.
 * Intended to be called by multiple different server tasks, including external code.
 *
 * Inputs: 
 *   pszAccessToken   - Points to the B64url encoded signed JWT to validate
 *   pszProviderURL   - Base URL of trusted OIDC provider for this connection
 *   pszRequiredScope - "Domino.user.all" or equivalent
 *   pszResourceURL   - Expected value in audience (aud) claim, such as https://www.example.com
 *   dwFlags          - Modify behavior from defaults. See fJWT_validate_* below.
 *   vpOptionalParams - Optional. If non-NULL, must point to a JWT_VALIDATE_OPTIONAL_PARAMS structure
 *   pOptionalParams->pszCustomClaimName
 *   pOptionalParams->ResourceCallback
 *   pOptionalParams->AllowedClientID
 *   dwMaxEmailSize   - Size of retszEmail buffer
 *   retszEmail        - Points to buffer to receive output
 *   retdwDurationSec - Optional. Points to DWORD to receive output
 *
 * Outputs:
 *   *retpEmail        - On success, filled in with email address from JWT
 *   *retdwDurationSec - Optional. On success, filled in with seconds left before expiration
 *
 * Common return values:
 *   ERR_BSAFE_NULLPARAM       - Invalid NULL inputs or no trusted OIDC providers
 *   ERR_BSAFE_NON_EXISTENT    - OIDC Provider not initialized or cannot be used for bearerAuth
 *   ERR_BSAFE_TOOSMALL        - Email address larger than dwMaxEmailSize
 *   ERR_BSAFE_BAD_ATTRIBUTES  - JWT lacking mandatory attributes or issuer/aud/scope/azp not matching
 *   ERR_BSAFE_CERT_VALIDITY   - JWT issued in the future
 *   ERR_SECURE_EXPIRED_CERT   - JWT expired in the past
 *   ERR_BSAFE_BAD_SIGNATURE   - Invalid signature on JWT
 *   ERR_BSAFE_BAD_OPCODE      - Unsupported combination of signing algorithm and key
 * 
 */
typedef BOOL (*ResourceCallback) (char *pszAudience, void *vpCallerContext);
typedef BOOL (*ClientCallback) (char *pAzp, void *vpCallerContext);

typedef struct {
    char *pszCustomClaimName;
    ResourceCallback AllowedResource;
    ClientCallback AllowedClientID;
    void           *vpCallerContext; /* caller context data to be passed back to caller */
} JWT_VALIDATE_OPTIONAL_PARAMS;

/* Allow expired JWTs. Intended for testing purposes only. */
#define fJWT_validate_AllowExpired          0x00000001

/* If set, Domino will tolerate standards violations known to be used by Azure AD and ADFS 2019 */
#define fJWT_validate_AllowMSWorkarounds    0x00000002

/* If set, Domino will look for the claim name from pOptionalParams->pszCustomClaimName before the "email" Claim */
#define fJWT_validate_UseCustomEmailClaim   0x00000010

/* If set, Domino will call the pOptionalParams->ResourceCallback for each audience in the "aud" Claim. At least one must be allowed (returns TRUE) for the token to be valid */
#define fJWT_validate_AllowAlternateAud     0x00000020

/* If set, Domino will call the pOptionalParams->AllowedClientID callback with the value of the "azp" Claim. This callback must return TRUE for the token to be valid. */
#define fJWT_validate_EnforceAllowedClients 0x00000040

STATUS LNPUBLIC SECValidateAccessToken (const char *pszAccessToken,
                                        const char *pszProviderURL,
                                        const char *pszRequiredScope,
                                        const char *pszResourceURL,
                                        DWORD      dwFlags,
                                        void       *vpOptionalParams,
                                        DWORD      dwMaxEmailSize,
                                        char       *retszEmail,
                                        DWORD      *retdwDurationSec);