001/* 002 * acme4j - Java ACME client 003 * 004 * Copyright (C) 2015 Richard "Shred" Körber 005 * http://acme4j.shredzone.org 006 * 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 013 */ 014package org.shredzone.acme4j.challenge; 015 016import static org.shredzone.acme4j.toolbox.AcmeUtils.base64UrlEncode; 017 018import org.shredzone.acme4j.Login; 019import org.shredzone.acme4j.exception.AcmeProtocolException; 020import org.shredzone.acme4j.toolbox.AcmeUtils; 021import org.shredzone.acme4j.toolbox.JSON; 022import org.shredzone.acme4j.toolbox.JoseUtils; 023 024/** 025 * A generic extension of {@link Challenge} that handles challenges with a {@code token} 026 * and {@code keyAuthorization}. 027 */ 028public class TokenChallenge extends Challenge { 029 private static final long serialVersionUID = 1634133407432681800L; 030 031 protected static final String KEY_TOKEN = "token"; 032 033 /** 034 * Creates a new generic {@link TokenChallenge} object. 035 * 036 * @param login 037 * {@link Login} the resource is bound with 038 * @param data 039 * {@link JSON} challenge data 040 */ 041 public TokenChallenge(Login login, JSON data) { 042 super(login, data); 043 } 044 045 /** 046 * Gets the token. 047 */ 048 protected String getToken() { 049 var token = getJSON().get(KEY_TOKEN).asString(); 050 if (!AcmeUtils.isValidBase64Url(token)) { 051 throw new AcmeProtocolException("Invalid token: " + token); 052 } 053 return token; 054 } 055 056 /** 057 * Computes the key authorization for the given token. 058 * <p> 059 * The default is {@code token + '.' + base64url(jwkThumbprint)}. Subclasses may 060 * override this method if a different algorithm is used. 061 * 062 * @param token 063 * Token to be used 064 * @return Key Authorization string for that token 065 * @since 2.12 066 */ 067 protected String keyAuthorizationFor(String token) { 068 var pk = getLogin().getKeyPair().getPublic(); 069 return token + '.' + base64UrlEncode(JoseUtils.thumbprint(pk)); 070 } 071 072 /** 073 * Returns the authorization string. 074 * <p> 075 * The default uses {@link #keyAuthorizationFor(String)} to compute the key 076 * authorization of {@link #getToken()}. Subclasses may override this method if a 077 * different algorithm is used. 078 */ 079 public String getAuthorization() { 080 return keyAuthorizationFor(getToken()); 081 } 082 083}