1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.net.eap; 18 19 import static com.android.internal.net.eap.EapAuthenticator.LOG; 20 import static com.android.internal.net.eap.statemachine.EapMethodStateMachine.MIN_EMSK_LEN_BYTES; 21 import static com.android.internal.net.eap.statemachine.EapMethodStateMachine.MIN_MSK_LEN_BYTES; 22 23 import android.annotation.NonNull; 24 25 import com.android.internal.annotations.VisibleForTesting; 26 import com.android.internal.net.eap.exceptions.InvalidEapResponseException; 27 import com.android.internal.net.eap.message.EapMessage; 28 29 /** 30 * EapResult represents the return type R for a process operation within the EapStateMachine. 31 */ 32 public abstract class EapResult { 33 34 /** 35 * EapSuccess represents a success response from the EapStateMachine. 36 * 37 * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication 38 * Protocol (EAP)</a> 39 */ 40 public static class EapSuccess extends EapResult { 41 private static final String TAG = EapSuccess.class.getSimpleName(); 42 43 public final byte[] msk; 44 public final byte[] emsk; 45 EapSuccess(@onNull byte[] msk, @NonNull byte[] emsk)46 public EapSuccess(@NonNull byte[] msk, @NonNull byte[] emsk) { 47 if (msk == null || emsk == null) { 48 throw new IllegalArgumentException("msk and emsk must not be null"); 49 } 50 if (msk.length < MIN_MSK_LEN_BYTES || emsk.length < MIN_EMSK_LEN_BYTES) { 51 LOG.wtf( 52 TAG, 53 "MSK or EMSK does not meet the required key length: MSK=" 54 + LOG.pii(msk) 55 + " EMSK=" 56 + LOG.pii(emsk)); 57 } 58 this.msk = msk; 59 this.emsk = emsk; 60 } 61 } 62 63 /** 64 * EapFailure represents a failure response from the EapStateMachine. 65 * 66 * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication 67 * Protocol (EAP)</a> 68 */ 69 public static class EapFailure extends EapResult {} 70 71 /** 72 * EapResponse represents an outgoing message from the EapStateMachine. 73 * 74 * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication 75 * Protocol (EAP)</a> 76 */ 77 public static class EapResponse extends EapResult { 78 public final byte[] packet; 79 80 @VisibleForTesting EapResponse(byte[] packet)81 protected EapResponse(byte[] packet) { 82 this.packet = packet; 83 } 84 85 /** 86 * Constructs and returns an EapResult for the given EapMessage. 87 * 88 * <p>If the given EapMessage is not of type EAP-Response, an EapError object will be 89 * returned. 90 * 91 * @param message the EapMessage to be encoded in the EapResponse instance. 92 * @return an EapResponse instance for the given message. If message.eapCode != {@link 93 * EapMessage#EAP_CODE_RESPONSE}, an EapError instance is returned. 94 */ getEapResponse(@onNull EapMessage message)95 public static EapResult getEapResponse(@NonNull EapMessage message) { 96 if (message == null) { 97 throw new IllegalArgumentException("EapMessage should not be null"); 98 } else if (message.eapCode != EapMessage.EAP_CODE_RESPONSE) { 99 return new EapError(new InvalidEapResponseException( 100 "Cannot construct an EapResult from a non-EAP-Response message")); 101 } 102 103 return new EapResponse(message.encode()); 104 } 105 } 106 107 /** 108 * EapError represents an error that occurred in the EapStateMachine. 109 * 110 * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication 111 * Protocol (EAP)</a> 112 */ 113 public static class EapError extends EapResult { 114 public final Exception cause; 115 116 /** 117 * Constructs an EapError instance for the given cause. 118 * 119 * @param cause the Exception that caused the EapError to be returned from the 120 * EapStateMachine 121 */ EapError(Exception cause)122 public EapError(Exception cause) { 123 this.cause = cause; 124 } 125 } 126 } 127