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 java.security.PublicKey; 019 020import org.shredzone.acme4j.Login; 021import org.shredzone.acme4j.exception.AcmeProtocolException; 022import org.shredzone.acme4j.toolbox.AcmeUtils; 023import org.shredzone.acme4j.toolbox.JSON; 024import org.shredzone.acme4j.toolbox.JoseUtils; 025 026/** 027 * An extension of {@link Challenge} that handles challenges with a {@code token} and 028 * {@code keyAuthorization}. 029 */ 030public class TokenChallenge extends Challenge { 031 private static final long serialVersionUID = 1634133407432681800L; 032 033 protected static final String KEY_TOKEN = "token"; 034 035 /** 036 * Creates a new generic {@link TokenChallenge} object. 037 * 038 * @param login 039 * {@link Login} the resource is bound with 040 * @param data 041 * {@link JSON} challenge data 042 */ 043 public TokenChallenge(Login login, JSON data) { 044 super(login, data); 045 } 046 047 /** 048 * Gets the token. 049 */ 050 protected String getToken() { 051 String token = getJSON().get(KEY_TOKEN).asString(); 052 if (!AcmeUtils.isValidBase64Url(token)) { 053 throw new AcmeProtocolException("Invalid token: " + token); 054 } 055 return token; 056 } 057 058 /** 059 * Computes the key authorization for the given token. 060 * <p> 061 * The default is {@code token + '.' + base64url(jwkThumbprint)}. Subclasses may 062 * override this method if a different algorithm is used. 063 * 064 * @param token 065 * Token to be used 066 * @return Key Authorization string for that token 067 * @since 2.12 068 */ 069 protected String keyAuthorizationFor(String token) { 070 PublicKey pk = getLogin().getKeyPair().getPublic(); 071 return token + '.' + base64UrlEncode(JoseUtils.thumbprint(pk)); 072 } 073 074 /** 075 * Returns the authorization string. 076 * <p> 077 * The default uses {@link #keyAuthorizationFor(String)} to compute the key 078 * authorization of {@link #getToken()}. Subclasses may override this method if a 079 * different algorithm is used. 080 */ 081 public String getAuthorization() { 082 return keyAuthorizationFor(getToken()); 083 } 084 085}