1 /* 2 * Copyright (C) 2020 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 android.ipsec.ike.cts; 18 19 import static com.android.internal.util.HexDump.hexStringToByteArray; 20 21 import android.ipsec.ike.cts.IkeTunUtils.PortPair; 22 import android.net.InetAddresses; 23 import android.net.LinkAddress; 24 import android.net.ipsec.ike.IkeFqdnIdentification; 25 import android.net.ipsec.ike.IkeSession; 26 import android.net.ipsec.ike.IkeSessionParams; 27 import android.net.ipsec.ike.IkeTrafficSelector; 28 29 import androidx.test.ext.junit.runners.AndroidJUnit4; 30 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 34 import java.net.InetAddress; 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 38 /** 39 * Explicitly test transport mode Child SA so that devices without FEATURE_IPSEC_TUNNELS can be test 40 * covered. Tunnel mode Child SA setup has been tested in IkeSessionPskTest. Rekeying process is 41 * independent from Child SA mode. 42 */ 43 @RunWith(AndroidJUnit4.class) 44 public class IkeSessionRekeyTest extends IkeSessionTestBase { 45 // This value is align with the test vectors hex that are generated in an IPv4 environment 46 private static final IkeTrafficSelector TRANSPORT_MODE_INBOUND_TS = 47 new IkeTrafficSelector( 48 MIN_PORT, 49 MAX_PORT, 50 InetAddresses.parseNumericAddress("172.58.35.40"), 51 InetAddresses.parseNumericAddress("172.58.35.40")); 52 openIkeSessionWithRemoteAddress(InetAddress remoteAddress)53 private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) { 54 IkeSessionParams ikeParams = 55 new IkeSessionParams.Builder(sContext) 56 .setNetwork(mTunNetworkContext.tunNetwork) 57 .setServerHostname(remoteAddress.getHostAddress()) 58 .addSaProposal(SaProposalTest.buildIkeSaProposalWithNormalModeCipher()) 59 .addSaProposal(SaProposalTest.buildIkeSaProposalWithCombinedModeCipher()) 60 .setLocalIdentification(new IkeFqdnIdentification(LOCAL_HOSTNAME)) 61 .setRemoteIdentification(new IkeFqdnIdentification(REMOTE_HOSTNAME)) 62 .setAuthPsk(IKE_PSK) 63 .build(); 64 return new IkeSession( 65 sContext, 66 ikeParams, 67 buildTransportModeChildParamsWithTs( 68 TRANSPORT_MODE_INBOUND_TS, TRANSPORT_MODE_OUTBOUND_TS), 69 mUserCbExecutor, 70 mIkeSessionCallback, 71 mFirstChildSessionCallback); 72 } 73 buildInboundPkt(PortPair outPktSrcDestPortPair, String inboundDataHex)74 private byte[] buildInboundPkt(PortPair outPktSrcDestPortPair, String inboundDataHex) 75 throws Exception { 76 // Build inbound packet by flipping the outbound packet addresses and ports 77 return IkeTunUtils.buildIkePacket( 78 mRemoteAddress, 79 mLocalAddress, 80 outPktSrcDestPortPair.dstPort, 81 outPktSrcDestPortPair.srcPort, 82 true /* useEncap */, 83 hexStringToByteArray(inboundDataHex)); 84 } 85 86 @Test testRekeyIke()87 public void testRekeyIke() throws Exception { 88 final String ikeInitResp = 89 "46B8ECA1E0D72A1866B5248CF6C7472D21202220000000000000015022000030" 90 + "0000002C010100040300000C0100000C800E0100030000080300000C03000008" 91 + "0200000500000008040000022800008800020000920D3E830E7276908209212D" 92 + "E5A7F2A48706CFEF1BE8CB6E3B173B8B4E0D8C2DC626271FF1B13A88619E569E" 93 + "7B03C3ED2C127390749CDC7CDC711D0A8611E4457FFCBC4F0981B3288FBF58EA" 94 + "3E8B70E27E76AE70117FBBCB753660ADDA37EB5EB3A81BED6A374CCB7E132C2A" 95 + "94BFCE402DC76B19C158B533F6B1F2ABF01ACCC329000024B302CA2FB85B6CF4" 96 + "02313381246E3C53828D787F6DFEA6BD62D6405254AEE6242900001C00004004" 97 + "7A1682B06B58596533D00324886EF1F20EF276032900001C00004005BF633E31" 98 + "F9984B29A62E370BB2770FC09BAEA665290000080000402E290000100000402F" 99 + "00020003000400050000000800004014"; 100 final String ikeAuthResp = 101 "46B8ECA1E0D72A1866B5248CF6C7472D2E20232000000001000000F0240000D4" 102 + "10166CA8647F56123DE74C17FA5E256043ABF73216C812EE32EE1BB01EAF4A82" 103 + "DC107AB3ADBFEE0DEA5EEE10BDD5D43178F4C975C7C775D252273BB037283C7F" 104 + "236FE34A6BCE4833816897075DB2055B9FFD66DFA45A0A89A8F70AFB59431EED" 105 + "A20602FB614369D12906D3355CF7298A5D25364ABBCC75A9D88E0E6581449FCD" 106 + "4E361A39E00EFD1FD0A69651F63DB46C12470226AA21BA5EFF48FAF0B6DDF61C" 107 + "B0A69392CE559495EEDB4D1C1D80688434D225D57210A424C213F7C993D8A456" 108 + "38153FBD194C5E247B592D1D048DB4C8"; 109 final String rekeyIkeCreateReq = 110 "46B8ECA1E0D72A1866B5248CF6C7472D2E202400000000000000013021000114" 111 + "13743670039E308A8409BA5FD47B67F956B36FEE88AC3B70BB5D789B8218A135" 112 + "1B3D83E260E87B3EDB1BF064F09D4DC2611AEDBC99951B4B2DE767BD4AA2ACC3" 113 + "3653549CFC66B75869DF003CDC9A137A9CC27776AD5732B34203E74BE8CA4858" 114 + "1D5C0D9C9CA52D680EB299B4B21C7FA25FFEE174D57015E0FF2EAED653AAD95C" 115 + "071ABE269A8C2C9FBC1188E07550EB992F910D4CA9689E44BA66DE0FABB2BDF9" 116 + "8DD377186DBB25EF9B68B027BB2A27981779D8303D88D7CE860010A42862D50B" 117 + "1E0DBFD3D27C36F14809D7F493B2B96A65534CF98B0C32AD5219AD77F681AC04" 118 + "9D5CB89A0230A91A243FA7F16251B0D9B4B65E7330BEEAC9663EF4578991EAC8" 119 + "46C19EBB726E7D113F1D0D601102C05E"; 120 final String rekeyIkeDeleteReq = 121 "46B8ECA1E0D72A1866B5248CF6C7472D2E20250000000001000000502A000034" 122 + "02E40C0C7B1ED977729F705BB9B643FAC513A1070A6EB28ECD2AEA8A441ADC05" 123 + "7841382A7967BBF116AE52496590B2AD"; 124 final String deleteIkeReq = 125 "7D3DEDC65407D1FC9361C8CF8C47162A2E20250800000000000000502A000034" 126 + "201915C9E4E9173AA9EE79F3E02FE2D4954B22085C66D164762C34D347C16E9F" 127 + "FC5F7F114428C54D8D915860C57B1BC1"; 128 final long newIkeDeterministicInitSpi = Long.parseLong("7D3DEDC65407D1FC", 16); 129 130 // Open IKE Session 131 IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); 132 PortPair localRemotePorts = performSetupIkeAndFirstChildBlocking(ikeInitResp, ikeAuthResp); 133 134 // Local request message ID starts from 2 because there is one IKE_INIT message and a single 135 // IKE_AUTH message. 136 int expectedReqMsgId = 2; 137 int expectedRespMsgId = 0; 138 139 verifyIkeSessionSetupBlocking(); 140 verifyChildSessionSetupBlocking( 141 mFirstChildSessionCallback, 142 Arrays.asList(TRANSPORT_MODE_INBOUND_TS), 143 Arrays.asList(TRANSPORT_MODE_OUTBOUND_TS), 144 new ArrayList<LinkAddress>()); 145 IpSecTransformCallRecord firstTransformRecordA = 146 mFirstChildSessionCallback.awaitNextCreatedIpSecTransform(); 147 IpSecTransformCallRecord firstTransformRecordB = 148 mFirstChildSessionCallback.awaitNextCreatedIpSecTransform(); 149 verifyCreateIpSecTransformPair(firstTransformRecordA, firstTransformRecordB); 150 151 // Inject rekey IKE requests 152 mTunNetworkContext.tunUtils.injectPacket( 153 buildInboundPkt(localRemotePorts, rekeyIkeCreateReq)); 154 mTunNetworkContext.tunUtils.awaitResp( 155 IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */); 156 mTunNetworkContext.tunUtils.injectPacket( 157 buildInboundPkt(localRemotePorts, rekeyIkeDeleteReq)); 158 mTunNetworkContext.tunUtils.awaitResp( 159 IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */); 160 161 // IKE has been rekeyed, reset message IDs 162 expectedReqMsgId = 0; 163 expectedRespMsgId = 0; 164 165 // Inject delete IKE request 166 mTunNetworkContext.tunUtils.injectPacket(buildInboundPkt(localRemotePorts, deleteIkeReq)); 167 mTunNetworkContext.tunUtils.awaitResp( 168 newIkeDeterministicInitSpi, expectedRespMsgId++, true /* expectedUseEncap */); 169 170 verifyDeleteIpSecTransformPair( 171 mFirstChildSessionCallback, firstTransformRecordA, firstTransformRecordB); 172 mFirstChildSessionCallback.awaitOnClosed(); 173 mIkeSessionCallback.awaitOnClosed(); 174 } 175 176 @Test testRekeyTransportModeChildSa()177 public void testRekeyTransportModeChildSa() throws Exception { 178 final String ikeInitResp = 179 "46B8ECA1E0D72A18CECD871146CF83A121202220000000000000015022000030" 180 + "0000002C010100040300000C0100000C800E0100030000080300000C03000008" 181 + "0200000500000008040000022800008800020000C4904458957746BCF1C12972" 182 + "1D4E19EB8A584F78DE673053396D167CE0F34552DBC69BA63FE7C673B4CF4A99" 183 + "62481518EE985357876E8C47BAAA0DBE9C40AE47B12E52165874703586E8F786" 184 + "045F72EEEB238C5D1823352BED44B71B3214609276ADC0B3D42DAC820168C4E2" 185 + "660730DAAC92492403288805EBB9053F1AB060DA290000242D9364ACB93519FF" 186 + "8F8B019BAA43A40D699F59714B327B8382216EF427ED52282900001C00004004" 187 + "06D91438A0D6B734E152F76F5CC55A72A2E38A0A2900001C000040052EFF78B3" 188 + "55B37F3CE75AFF26C721B050F892C0D6290000080000402E290000100000402F" 189 + "00020003000400050000000800004014"; 190 final String ikeAuthResp = 191 "46B8ECA1E0D72A18CECD871146CF83A12E20232000000001000000F0240000D4" 192 + "A17BC258BA2714CF536663639DD5F665A60C75E93557CD5141990A8CEEDD2017" 193 + "93F5B181C8569FBCD6C2A00198EC2B62D42BEFAC016B8B6BF6A7BC9CEDE3413A" 194 + "6C495A6B8EC941864DC3E08F57D015EA6520C4B05884960B85478FCA53DA5F17" 195 + "9628BB1097DA77461C71837207A9EB80720B3E6E661816EE4E14AC995B5E8441" 196 + "A4C3F9097CC148142BA300076C94A23EC4ADE82B1DD2B121F7E9102860A8C3BF" 197 + "58DDC207285A3176E924C44DE820322524E1AA438EFDFBA781B36084AED80846" 198 + "3B77FCED9682B6E4E476408EF3F1037E"; 199 final String rekeyChildCreateReq = 200 "46B8ECA1E0D72A18CECD871146CF83A12E202400000000000000015029000134" 201 + "319D74B6B155B86942143CEC1D29D21F073F24B7BEDC9BFE0F0FDD8BDB5458C0" 202 + "8DB93506E1A43DD0640FE7370C97F9B34FF4EC9B2DB7257A87B75632301FB68A" 203 + "86B54871249534CA3D01C9BEB127B669F46470E1C8AAF72574C3CEEC15B901CF" 204 + "5A0D6ADAE59C3CA64AC8C86689C860FAF9500E608DFE63F2DCD30510FD6FFCD5" 205 + "A50838574132FD1D069BCACD4C7BAF45C9B1A7689FAD132E3F56DBCFAF905A8C" 206 + "4145D4BA1B74A54762F8F43308D94DE05649C49D885121CE30681D51AC1E3E68" 207 + "AB82F9A19B99579AFE257F32DBD1037814DA577379E4F42DEDAC84502E49C933" 208 + "9EA83F6F5DB4401B660CB1681B023B8603D205DFDD1DE86AD8DE22B6B754F30D" 209 + "05EAE81A709C2CEE81386133DC3DC7B5EF8F166E48E54A0722DD0C64F4D00638" 210 + "40F272144C47F6ECED72A248180645DB"; 211 final String rekeyChildDeleteReq = 212 "46B8ECA1E0D72A18CECD871146CF83A12E20250000000001000000502A000034" 213 + "02D98DAF0432EBD991CA4F2D89C1E0EFABC6E91A3327A85D8914FB2F1485BE1B" 214 + "8D3415D548F7CE0DC4224E7E9D0D3355"; 215 final String deleteIkeReq = 216 "46B8ECA1E0D72A18CECD871146CF83A12E20250000000002000000502A000034" 217 + "095041F4026B4634F04B0AB4F9349484F7BE9AEF03E3733EEE293330043B75D2" 218 + "ABF5F965ED51127629585E1B1BBA787F"; 219 220 // Open IKE Session 221 IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress); 222 PortPair localRemotePorts = performSetupIkeAndFirstChildBlocking(ikeInitResp, ikeAuthResp); 223 224 // IKE INIT and IKE AUTH takes two exchanges. Local request message ID starts from 2 225 int expectedReqMsgId = 2; 226 int expectedRespMsgId = 0; 227 228 verifyIkeSessionSetupBlocking(); 229 verifyChildSessionSetupBlocking( 230 mFirstChildSessionCallback, 231 Arrays.asList(TRANSPORT_MODE_INBOUND_TS), 232 Arrays.asList(TRANSPORT_MODE_OUTBOUND_TS), 233 new ArrayList<LinkAddress>()); 234 IpSecTransformCallRecord oldTransformRecordA = 235 mFirstChildSessionCallback.awaitNextCreatedIpSecTransform(); 236 IpSecTransformCallRecord oldTransformRecordB = 237 mFirstChildSessionCallback.awaitNextCreatedIpSecTransform(); 238 verifyCreateIpSecTransformPair(oldTransformRecordA, oldTransformRecordB); 239 240 // Inject rekey Child requests 241 mTunNetworkContext.tunUtils.injectPacket( 242 buildInboundPkt(localRemotePorts, rekeyChildCreateReq)); 243 mTunNetworkContext.tunUtils.awaitResp( 244 IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */); 245 mTunNetworkContext.tunUtils.injectPacket( 246 buildInboundPkt(localRemotePorts, rekeyChildDeleteReq)); 247 mTunNetworkContext.tunUtils.awaitResp( 248 IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */); 249 250 // Verify IpSecTransforms are renewed 251 IpSecTransformCallRecord newTransformRecordA = 252 mFirstChildSessionCallback.awaitNextCreatedIpSecTransform(); 253 IpSecTransformCallRecord newTransformRecordB = 254 mFirstChildSessionCallback.awaitNextCreatedIpSecTransform(); 255 verifyCreateIpSecTransformPair(newTransformRecordA, newTransformRecordB); 256 verifyDeleteIpSecTransformPair( 257 mFirstChildSessionCallback, oldTransformRecordA, oldTransformRecordB); 258 259 // Inject delete IKE request 260 mTunNetworkContext.tunUtils.injectPacket(buildInboundPkt(localRemotePorts, deleteIkeReq)); 261 mTunNetworkContext.tunUtils.awaitResp( 262 IKE_DETERMINISTIC_INITIATOR_SPI, expectedRespMsgId++, true /* expectedUseEncap */); 263 264 verifyDeleteIpSecTransformPair( 265 mFirstChildSessionCallback, newTransformRecordA, newTransformRecordB); 266 mFirstChildSessionCallback.awaitOnClosed(); 267 mIkeSessionCallback.awaitOnClosed(); 268 } 269 } 270