1 /*
   2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.oracle.security.ucrypto;
  27 
  28 import java.util.*;
  29 import java.security.ProviderException;
  30 
  31 /**
  32  * The exception class used by SunUcrypto provider. An exception
  33  * object of this class indicates that a function call to the underlying
  34  * native calls returned a value not equal to CRYPTO_SUCCESS.
  35  *
  36  * @since 9
  37  */
  38 public final class UcryptoException extends ProviderException {
  39 
  40     private static final long serialVersionUID = -933864511110035746L;
  41 
  42     // NOTE: check /usr/include/sys/crypto/common.h for updates
  43     public enum Error {
  44         CRYPTO_SUCCESS,
  45         CRYPTO_CANCEL,
  46         CRYPTO_HOST_MEMORY,
  47         CRYPTO_GENERAL_ERROR,
  48         CRYPTO_FAILED,
  49         CRYPTO_ARGUMENTS_BAD,
  50         CRYPTO_ATTRIBUTE_READ_ONLY,
  51         CRYPTO_ATTRIBUTE_SENSITIVE,
  52         CRYPTO_ATTRIBUTE_TYPE_INVALID,
  53         CRYPTO_ATTRIBUTE_VALUE_INVALID,
  54         CRYPTO_CANCELED,
  55         CRYPTO_DATA_INVALID,
  56         CRYPTO_DATA_LEN_RANGE,
  57         CRYPTO_DEVICE_ERROR,
  58         CRYPTO_DEVICE_MEMORY,
  59         CRYPTO_DEVICE_REMOVED,
  60         CRYPTO_ENCRYPTED_DATA_INVALID,
  61         CRYPTO_ENCRYPTED_DATA_LEN_RANGE,
  62         CRYPTO_KEY_HANDLE_INVALID,
  63         CRYPTO_KEY_SIZE_RANGE,
  64         CRYPTO_KEY_TYPE_INCONSISTENT,
  65         CRYPTO_KEY_NOT_NEEDED,
  66         CRYPTO_KEY_CHANGED,
  67         CRYPTO_KEY_NEEDED,
  68         CRYPTO_KEY_INDIGESTIBLE,
  69         CRYPTO_KEY_FUNCTION_NOT_PERMITTED,
  70         CRYPTO_KEY_NOT_WRAPPABLE,
  71         CRYPTO_KEY_UNEXTRACTABLE,
  72         CRYPTO_MECHANISM_INVALID,
  73         CRYPTO_MECHANISM_PARAM_INVALID,
  74         CRYPTO_OBJECT_HANDLE_INVALID,
  75         CRYPTO_OPERATION_IS_ACTIVE,
  76         CRYPTO_OPERATION_NOT_INITIALIZED,
  77         CRYPTO_PIN_INCORRECT,
  78         CRYPTO_PIN_INVALID,
  79         CRYPTO_PIN_LEN_RANGE,
  80         CRYPTO_PIN_EXPIRED,
  81         CRYPTO_PIN_LOCKED,
  82         CRYPTO_SESSION_CLOSED,
  83         CRYPTO_SESSION_COUNT,
  84         CRYPTO_SESSION_HANDLE_INVALID,
  85         CRYPTO_SESSION_READ_ONLY,
  86         CRYPTO_SESSION_EXISTS,
  87         CRYPTO_SESSION_READ_ONLY_EXISTS,
  88         CRYPTO_SESSION_READ_WRITE_SO_EXISTS,
  89         CRYPTO_SIGNATURE_INVALID,
  90         CRYPTO_SIGNATURE_LEN_RANGE,
  91         CRYPTO_TEMPLATE_INCOMPLETE,
  92         CRYPTO_TEMPLATE_INCONSISTENT,
  93         CRYPTO_UNWRAPPING_KEY_HANDLE_INVALID,
  94         CRYPTO_UNWRAPPING_KEY_SIZE_RANGE,
  95         CRYPTO_UNWRAPPING_KEY_TYPE_INCONSISTENT,
  96         CRYPTO_USER_ALREADY_LOGGED_IN,
  97         CRYPTO_USER_NOT_LOGGED_IN,
  98         CRYPTO_USER_PIN_NOT_INITIALIZED,
  99         CRYPTO_USER_TYPE_INVALID,
 100         CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN,
 101         CRYPTO_USER_TOO_MANY_TYPES,
 102         CRYPTO_WRAPPED_KEY_INVALID,
 103         CRYPTO_WRAPPED_KEY_LEN_RANGE,
 104         CRYPTO_WRAPPING_KEY_HANDLE_INVALID,
 105         CRYPTO_WRAPPING_KEY_SIZE_RANGE,
 106         CRYPTO_WRAPPING_KEY_TYPE_INCONSISTENT,
 107         CRYPTO_RANDOM_SEED_NOT_SUPPORTED,
 108         CRYPTO_RANDOM_NO_RNG,
 109         CRYPTO_DOMAIN_PARAMS_INVALID,
 110         CRYPTO_BUFFER_TOO_SMALL,
 111         CRYPTO_INFORMATION_SENSITIVE,
 112         CRYPTO_NOT_SUPPORTED,
 113         CRYPTO_QUEUED,
 114         CRYPTO_BUFFER_TOO_BIG,
 115         CRYPTO_INVALID_CONTEXT,
 116         CRYPTO_INVALID_MAC,
 117         CRYPTO_MECH_NOT_SUPPORTED,
 118         CRYPTO_INCONSISTENT_ATTRIBUTE,
 119         CRYPTO_NO_PERMISSION,
 120         CRYPTO_INVALID_PROVIDER_ID,
 121         CRYPTO_VERSION_MISMATCH,
 122         CRYPTO_BUSY,
 123         CRYPTO_UNKNOWN_PROVIDER,
 124         CRYPTO_MODVERIFICATION_FAILED,
 125         CRYPTO_OLD_CTX_TEMPLATE,
 126         CRYPTO_WEAK_KEY,
 127         CRYPTO_FIPS140_ERROR;
 128     };
 129 
 130     // Array used to look up error by ordinal
 131     private static final Error[] ALL_ERRORS = Error.values();
 132 
 133     /**
 134      * Get the error enum value (if any) associated with this exception.
 135      */
 136     public Error getError() {
 137         return (errorCode >= 0 && errorCode < ALL_ERRORS.length) ?
 138             ALL_ERRORS[errorCode] :
 139             null;
 140     }
 141 
 142     /**
 143      * The error code if this exception is triggered by a Ucrypto error.
 144      */
 145     private final int errorCode;
 146 
 147     /**
 148      * This method gets the corresponding text error message from a
 149      * predefined mapping. If mapping is not found, then it returns the error
 150      * code as a hex-string.
 151      *
 152      * @return The message or the error code; e.g. "CRYPTO_DATA_INVALID" or
 153      *         "0x88".
 154      */
 155     static String getErrorMessage(int errorCode) {
 156         String message;
 157         if (errorCode >= 0 && errorCode < ALL_ERRORS.length) {
 158             message = ALL_ERRORS[errorCode].name();
 159         } else {
 160             message = "0x" + Integer.toHexString(errorCode);
 161         }
 162         return message;
 163     }
 164 
 165     /**
 166      * Constructor taking the error code as defined for the CRYPTO_* constants
 167      */
 168     public UcryptoException(int rv) {
 169         super(getErrorMessage(rv));
 170         this.errorCode = rv;
 171     }
 172 
 173     public UcryptoException(String message) {
 174         super(message);
 175         errorCode = -1;
 176     }
 177 
 178     public UcryptoException(String message, Throwable cause) {
 179         super(message, cause);
 180         errorCode = -1;
 181     }
 182 
 183     /**
 184      * Returns the Ucrypto error code.
 185      *
 186      * @return The error code.
 187      */
 188     public int getErrorCode() {
 189         return errorCode;
 190     }
 191 }