001/* 002 * acme4j - Java ACME client 003 * 004 * Copyright (C) 2022 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.smime.exception; 015 016import static java.util.Collections.unmodifiableList; 017 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.List; 021import java.util.Optional; 022 023import org.bouncycastle.i18n.ErrorBundle; 024import org.bouncycastle.i18n.LocalizedException; 025import org.shredzone.acme4j.exception.AcmeException; 026 027/** 028 * This exception is thrown when the challenge email message is invalid. 029 * <p> 030 * If this exception is thrown, the challenge message does not match the actual challenge 031 * or has other issues. It <em>must</em> be rejected. 032 * <p> 033 * Reasons may be (for example): 034 * <ul> 035 * <li>Unexpected sender address</li> 036 * <li>Bad S/MIME signature</li> 037 * </ul> 038 * 039 * @since 2.15 040 */ 041public class AcmeInvalidMessageException extends AcmeException { 042 private static final long serialVersionUID = 5607857024718309330L; 043 044 private final List<ErrorBundle> errors; 045 046 /** 047 * Creates a new {@link AcmeInvalidMessageException}. 048 * 049 * @param msg 050 * Reason of the exception 051 */ 052 public AcmeInvalidMessageException(String msg) { 053 super(msg); 054 this.errors = Collections.emptyList(); 055 } 056 057 /** 058 * Creates a new {@link AcmeInvalidMessageException}. 059 * 060 * @param msg 061 * Reason of the exception 062 * @param errors 063 * List of {@link ErrorBundle} with further details 064 * @since 2.16 065 */ 066 public AcmeInvalidMessageException(String msg, List<ErrorBundle> errors) { 067 super(msg); 068 this.errors = unmodifiableList(errors); 069 } 070 071 /** 072 * Creates a new {@link AcmeInvalidMessageException}. 073 * 074 * @param msg 075 * Reason of the exception 076 * @param cause 077 * Cause 078 */ 079 public AcmeInvalidMessageException(String msg, Throwable cause) { 080 super(msg, cause); 081 var errors = new ArrayList<ErrorBundle>(1); 082 Optional.ofNullable(cause) 083 .filter(LocalizedException.class::isInstance) 084 .map(LocalizedException.class::cast) 085 .map(LocalizedException::getErrorMessage) 086 .ifPresent(errors::add); 087 this.errors = unmodifiableList(errors); 088 } 089 090 /** 091 * Returns a list with further error details, if available. The list may be empty, but 092 * is never {@code null}. 093 * 094 * @since 2.16 095 */ 096 public List<ErrorBundle> getErrors() { 097 return errors; 098 } 099 100}