1 /* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved 2 * 3 * The contents of this file is dual-licensed under 2 4 * alternative Open Source/Free licenses: LGPL 2.1 or later and 5 * Apache License 2.0. (starting with JNA version 4.0.0). 6 * 7 * You can freely decide which license you want to apply to 8 * the project. 9 * 10 * You may obtain a copy of the LGPL License at: 11 * 12 * http://www.gnu.org/licenses/licenses.html 13 * 14 * A copy is also included in the downloadable source code package 15 * containing JNA, in file "LGPL2.1". 16 * 17 * You may obtain a copy of the Apache License at: 18 * 19 * http://www.apache.org/licenses/ 20 * 21 * A copy is also included in the downloadable source code package 22 * containing JNA, in file "AL2.0". 23 */ 24 package com.sun.jna.platform.win32; 25 26 import com.sun.jna.Memory; 27 import com.sun.jna.Native; 28 import com.sun.jna.platform.win32.SspiUtil.ManagedSecBufferDesc; 29 import com.sun.jna.platform.win32.Sspi.CredHandle; 30 import com.sun.jna.platform.win32.Sspi.CtxtHandle; 31 import com.sun.jna.platform.win32.Sspi.PSecPkgInfo; 32 import com.sun.jna.platform.win32.Sspi.SecPkgContext_PackageInfo; 33 import com.sun.jna.platform.win32.Sspi.SecPkgContext_Sizes; 34 import com.sun.jna.platform.win32.Sspi.SecPkgCredentials_Names; 35 import com.sun.jna.platform.win32.Sspi.SecPkgInfo; 36 import com.sun.jna.platform.win32.Sspi.SecPkgInfo.ByReference; 37 import com.sun.jna.platform.win32.Sspi.TimeStamp; 38 import com.sun.jna.platform.win32.WinNT.HANDLEByReference; 39 import com.sun.jna.ptr.IntByReference; 40 import java.nio.charset.Charset; 41 import java.util.Arrays; 42 43 import junit.framework.TestCase; 44 45 /** 46 * @author dblock[at]dblock[dot]org 47 */ 48 public class Secur32Test extends TestCase { 49 main(String[] args)50 public static void main(String[] args) { 51 junit.textui.TestRunner.run(Secur32Test.class); 52 } 53 54 @Override tearDown()55 protected void tearDown() throws Exception { 56 super.tearDown(); 57 // Drain last error to prevent test fails from lingering last error 58 // states 59 Kernel32.INSTANCE.GetLastError(); 60 } 61 testGetUserNameEx()62 public void testGetUserNameEx() { 63 IntByReference len = new IntByReference(); 64 Secur32.INSTANCE.GetUserNameEx( 65 Secur32.EXTENDED_NAME_FORMAT.NameSamCompatible, null, len); 66 assertTrue(len.getValue() > 0); 67 char[] buffer = new char[len.getValue() + 1]; 68 assertTrue(Secur32.INSTANCE.GetUserNameEx( 69 Secur32.EXTENDED_NAME_FORMAT.NameSamCompatible, buffer, len)); 70 String username = Native.toString(buffer); 71 assertTrue(username.length() > 0); 72 } 73 testAcquireCredentialsHandle()74 public void testAcquireCredentialsHandle() { 75 CredHandle phCredential = new CredHandle(); 76 TimeStamp ptsExpiry = new TimeStamp(); 77 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 78 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 79 null, phCredential, ptsExpiry)); 80 assertTrue(phCredential.dwLower != null); 81 assertTrue(phCredential.dwUpper != null); 82 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 83 phCredential)); 84 } 85 testAcquireCredentialsHandleInvalidPackage()86 public void testAcquireCredentialsHandleInvalidPackage() { 87 CredHandle phCredential = new CredHandle(); 88 TimeStamp ptsExpiry = new TimeStamp(); 89 assertEquals(W32Errors.SEC_E_SECPKG_NOT_FOUND, Secur32.INSTANCE.AcquireCredentialsHandle( 90 null, "PackageDoesntExist", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 91 null, phCredential, ptsExpiry)); 92 } 93 testInitializeSecurityContext()94 public void testInitializeSecurityContext() { 95 CredHandle phCredential = new CredHandle(); 96 TimeStamp ptsExpiry = new TimeStamp(); 97 // acquire a credentials handle 98 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 99 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 100 null, phCredential, ptsExpiry)); 101 // initialize security context 102 CtxtHandle phNewContext = new CtxtHandle(); 103 ManagedSecBufferDesc pbToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 104 IntByReference pfContextAttr = new IntByReference(); 105 int rc = Secur32.INSTANCE.InitializeSecurityContext(phCredential, null, 106 Advapi32Util.getUserName(), Sspi.ISC_REQ_CONNECTION, 0, 107 Sspi.SECURITY_NATIVE_DREP, null, 0, phNewContext, pbToken, 108 pfContextAttr, null); 109 assertTrue(rc == W32Errors.SEC_I_CONTINUE_NEEDED || rc == W32Errors.SEC_E_OK); 110 assertTrue(phNewContext.dwLower != null); 111 assertTrue(phNewContext.dwUpper != null); 112 assertTrue(pbToken.getBuffer(0).getBytes().length > 0); 113 // release 114 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 115 phNewContext)); 116 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 117 phCredential)); 118 } 119 testAcceptSecurityContext()120 public void testAcceptSecurityContext() { 121 // client ----------- acquire outbound credential handle 122 CredHandle phClientCredential = new CredHandle(); 123 TimeStamp ptsClientExpiry = new TimeStamp(); 124 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 125 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 126 null, phClientCredential, ptsClientExpiry)); 127 // client ----------- security context 128 CtxtHandle phClientContext = new CtxtHandle(); 129 IntByReference pfClientContextAttr = new IntByReference(); 130 // server ----------- acquire inbound credential handle 131 CredHandle phServerCredential = new CredHandle(); 132 TimeStamp ptsServerExpiry = new TimeStamp(); 133 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 134 null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, 135 null, phServerCredential, ptsServerExpiry)); 136 // server ----------- security context 137 CtxtHandle phServerContext = new CtxtHandle(); 138 ManagedSecBufferDesc pbServerToken = null; 139 IntByReference pfServerContextAttr = new IntByReference(); 140 int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; 141 int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; 142 do { 143 // client ----------- initialize security context, produce a client token 144 // client token returned is always new 145 ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 146 if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 147 // server token is empty the first time 148 ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null 149 ? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes()); 150 clientRc = Secur32.INSTANCE.InitializeSecurityContext( 151 phClientCredential, 152 phClientContext.isNull() ? null : phClientContext, 153 Advapi32Util.getUserName(), 154 Sspi.ISC_REQ_CONNECTION, 155 0, 156 Sspi.SECURITY_NATIVE_DREP, 157 pbServerTokenCopy, 158 0, 159 phClientContext, 160 pbClientToken, 161 pfClientContextAttr, 162 null); 163 assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); 164 } 165 // server ----------- accept security context, produce a server token 166 if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 167 pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 168 ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes()); 169 serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, 170 phServerContext.isNull() ? null : phServerContext, 171 pbClientTokenByValue, 172 Sspi.ISC_REQ_CONNECTION, 173 Sspi.SECURITY_NATIVE_DREP, 174 phServerContext, 175 pbServerToken, 176 pfServerContextAttr, 177 ptsServerExpiry); 178 assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); 179 } 180 } while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); 181 // release server context 182 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 183 phServerContext)); 184 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 185 phServerCredential)); 186 // release client context 187 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 188 phClientContext)); 189 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 190 phClientCredential)); 191 } 192 testImpersonateRevertSecurityContext()193 public void testImpersonateRevertSecurityContext() { 194 // client ----------- acquire outbound credential handle 195 CredHandle phClientCredential = new CredHandle(); 196 TimeStamp ptsClientExpiry = new TimeStamp(); 197 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 198 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 199 null, phClientCredential, ptsClientExpiry)); 200 // client ----------- security context 201 CtxtHandle phClientContext = new CtxtHandle(); 202 IntByReference pfClientContextAttr = new IntByReference(); 203 // server ----------- acquire inbound credential handle 204 CredHandle phServerCredential = new CredHandle(); 205 TimeStamp ptsServerExpiry = new TimeStamp(); 206 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 207 null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, 208 null, phServerCredential, ptsServerExpiry)); 209 // server ----------- security context 210 CtxtHandle phServerContext = new CtxtHandle(); 211 ManagedSecBufferDesc pbServerToken = null; 212 IntByReference pfServerContextAttr = new IntByReference(); 213 int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; 214 int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; 215 do { 216 // client ----------- initialize security context, produce a client token 217 // client token returned is always new 218 ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 219 if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 220 // server token is empty the first time 221 ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null 222 ? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes()); 223 clientRc = Secur32.INSTANCE.InitializeSecurityContext( 224 phClientCredential, 225 phClientContext.isNull() ? null : phClientContext, 226 Advapi32Util.getUserName(), 227 Sspi.ISC_REQ_CONNECTION, 228 0, 229 Sspi.SECURITY_NATIVE_DREP, 230 pbServerTokenCopy, 231 0, 232 phClientContext, 233 pbClientToken, 234 pfClientContextAttr, 235 null); 236 assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); 237 } 238 // server ----------- accept security context, produce a server token 239 if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 240 pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 241 ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes()); 242 serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, 243 phServerContext.isNull() ? null : phServerContext, 244 pbClientTokenByValue, 245 Sspi.ISC_REQ_CONNECTION, 246 Sspi.SECURITY_NATIVE_DREP, 247 phServerContext, 248 pbServerToken, 249 pfServerContextAttr, 250 ptsServerExpiry); 251 assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); 252 } 253 } while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); 254 // impersonate 255 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.ImpersonateSecurityContext( 256 phServerContext)); 257 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.RevertSecurityContext( 258 phServerContext)); 259 // release server context 260 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 261 phServerContext)); 262 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 263 phServerCredential)); 264 // release client context 265 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 266 phClientContext)); 267 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 268 phClientCredential)); 269 } 270 testEnumerateSecurityPackages()271 public void testEnumerateSecurityPackages() { 272 IntByReference pcPackages = new IntByReference(); 273 PSecPkgInfo.ByReference pPackageInfo = new PSecPkgInfo.ByReference(); 274 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.EnumerateSecurityPackages( 275 pcPackages, pPackageInfo)); 276 SecPkgInfo.ByReference[] packagesInfo = pPackageInfo.toArray( 277 pcPackages.getValue()); 278 for (SecPkgInfo.ByReference packageInfo : packagesInfo) { 279 assertTrue(packageInfo.Name.length() > 0); 280 assertTrue(packageInfo.Comment.length() >= 0); 281 } 282 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeContextBuffer( 283 pPackageInfo.pPkgInfo.getPointer())); 284 285 } 286 testQuerySecurityContextToken()287 public void testQuerySecurityContextToken() { 288 // client ----------- acquire outbound credential handle 289 CredHandle phClientCredential = new CredHandle(); 290 TimeStamp ptsClientExpiry = new TimeStamp(); 291 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 292 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 293 null, phClientCredential, ptsClientExpiry)); 294 // client ----------- security context 295 CtxtHandle phClientContext = new CtxtHandle(); 296 IntByReference pfClientContextAttr = new IntByReference(); 297 // server ----------- acquire inbound credential handle 298 CredHandle phServerCredential = new CredHandle(); 299 TimeStamp ptsServerExpiry = new TimeStamp(); 300 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 301 null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, 302 null, phServerCredential, ptsServerExpiry)); 303 // server ----------- security context 304 CtxtHandle phServerContext = new CtxtHandle(); 305 ManagedSecBufferDesc pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 306 IntByReference pfServerContextAttr = new IntByReference(); 307 int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; 308 int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; 309 do { 310 // client token returned is always new 311 ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 312 // client ----------- initialize security context, produce a client token 313 if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 314 // server token is empty the first time 315 clientRc = Secur32.INSTANCE.InitializeSecurityContext( 316 phClientCredential, 317 phClientContext.isNull() ? null : phClientContext, 318 Advapi32Util.getUserName(), 319 Sspi.ISC_REQ_CONNECTION, 320 0, 321 Sspi.SECURITY_NATIVE_DREP, 322 pbServerToken, 323 0, 324 phClientContext, 325 pbClientToken, 326 pfClientContextAttr, 327 null); 328 assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); 329 } 330 // server ----------- accept security context, produce a server token 331 if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 332 serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, 333 phServerContext.isNull() ? null : phServerContext, 334 pbClientToken, 335 Sspi.ISC_REQ_CONNECTION, 336 Sspi.SECURITY_NATIVE_DREP, 337 phServerContext, 338 pbServerToken, 339 pfServerContextAttr, 340 ptsServerExpiry); 341 assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); 342 } 343 } while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); 344 // query security context token 345 HANDLEByReference phContextToken = new HANDLEByReference(); 346 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.QuerySecurityContextToken( 347 phServerContext, phContextToken)); 348 // release security context token 349 Kernel32Util.closeHandleRef(phContextToken); 350 // release server context 351 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 352 phServerContext)); 353 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 354 phServerCredential)); 355 // release client context 356 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 357 phClientContext)); 358 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 359 phClientCredential)); 360 } 361 testCreateEmptyToken()362 public void testCreateEmptyToken() { 363 ManagedSecBufferDesc token = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 364 assertEquals(1, token.cBuffers); 365 assertEquals(Sspi.SECBUFFER_TOKEN, token.getBuffer(0).BufferType); 366 assertEquals(Sspi.MAX_TOKEN_SIZE, token.getBuffer(0).cbBuffer); 367 } 368 testQueryContextAttributes()369 public void testQueryContextAttributes() { 370 // client ----------- acquire outbound credential handle 371 CredHandle phClientCredential = new CredHandle(); 372 TimeStamp ptsClientExpiry = new TimeStamp(); 373 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 374 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 375 null, phClientCredential, ptsClientExpiry)); 376 // client ----------- security context 377 CtxtHandle phClientContext = new CtxtHandle(); 378 IntByReference pfClientContextAttr = new IntByReference(); 379 // server ----------- acquire inbound credential handle 380 CredHandle phServerCredential = new CredHandle(); 381 TimeStamp ptsServerExpiry = new TimeStamp(); 382 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 383 null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, 384 null, phServerCredential, ptsServerExpiry)); 385 // server ----------- security context 386 CtxtHandle phServerContext = new CtxtHandle(); 387 ManagedSecBufferDesc pbServerToken = null; 388 IntByReference pfServerContextAttr = new IntByReference(); 389 int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; 390 int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; 391 do { 392 // client ----------- initialize security context, produce a client token 393 // client token returned is always new 394 ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 395 if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 396 // server token is empty the first time 397 ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null 398 ? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes()); 399 clientRc = Secur32.INSTANCE.InitializeSecurityContext( 400 phClientCredential, 401 phClientContext.isNull() ? null : phClientContext, 402 Advapi32Util.getUserName(), 403 Sspi.ISC_REQ_CONNECTION, 404 0, 405 Sspi.SECURITY_NATIVE_DREP, 406 pbServerTokenCopy, 407 0, 408 phClientContext, 409 pbClientToken, 410 pfClientContextAttr, 411 null); 412 assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); 413 } 414 // server ----------- accept security context, produce a server token 415 if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 416 pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 417 ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes()); 418 serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, 419 phServerContext.isNull() ? null : phServerContext, 420 pbClientTokenByValue, 421 Sspi.ISC_REQ_CONNECTION, 422 Sspi.SECURITY_NATIVE_DREP, 423 phServerContext, 424 pbServerToken, 425 pfServerContextAttr, 426 ptsServerExpiry); 427 assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); 428 } 429 } while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); 430 // query context attributes 431 SecPkgContext_PackageInfo packageinfo = new SecPkgContext_PackageInfo(); 432 assertEquals(W32Errors.SEC_E_OK, 433 Secur32.INSTANCE.QueryContextAttributes(phServerContext, Sspi.SECPKG_ATTR_PACKAGE_INFO, packageinfo)); 434 ByReference info = packageinfo.PackageInfo; 435 436 assertNotNull(info.Name); 437 assertNotNull(info.Comment); 438 439 assertTrue(!info.Name.isEmpty()); 440 assertTrue(!info.Comment.isEmpty()); 441 442 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeContextBuffer(info.getPointer())); 443 444 // release server context 445 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(phServerContext)); 446 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(phServerCredential)); 447 // release client context 448 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext(phClientContext)); 449 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle(phClientCredential)); 450 } 451 testQuerySecurityPackageInfo()452 public void testQuerySecurityPackageInfo() { 453 PSecPkgInfo pkgInfo = new PSecPkgInfo(); 454 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.QuerySecurityPackageInfo("NTLM", pkgInfo)); 455 assertEquals(pkgInfo.pPkgInfo.Name, "NTLM"); 456 assertEquals(pkgInfo.pPkgInfo.fCapabilities & Sspi.SECPKG_FLAG_PRIVACY, Sspi.SECPKG_FLAG_PRIVACY); 457 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeContextBuffer(pkgInfo.getPointer())); 458 } 459 testQueryCredentialAttribute()460 public void testQueryCredentialAttribute() { 461 // acquire sample credential handle 462 CredHandle phClientCredential = new CredHandle(); 463 TimeStamp ptsClientExpiry = new TimeStamp(); 464 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle(null, "Negotiate", 465 Sspi.SECPKG_CRED_OUTBOUND, null, null, null, null, phClientCredential, ptsClientExpiry)); 466 467 SecPkgCredentials_Names names = new SecPkgCredentials_Names(); 468 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.QueryCredentialsAttributes(phClientCredential, Sspi.SECPKG_CRED_ATTR_NAMES, names)); 469 470 String accountName = names.getUserName(); 471 472 assertNotNull(accountName); 473 assertTrue(accountName.length() > 0); 474 475 assertEquals(W32Errors.SEC_E_OK, names.free()); 476 } 477 testEncryptDecryptMessage()478 public void testEncryptDecryptMessage() { 479 // client ----------- acquire outbound credential handle 480 CredHandle phClientCredential = new CredHandle(); 481 TimeStamp ptsClientExpiry = new TimeStamp(); 482 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 483 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 484 null, phClientCredential, ptsClientExpiry)); 485 // client ----------- security context 486 CtxtHandle phClientContext = new CtxtHandle(); 487 IntByReference pfClientContextAttr = new IntByReference(); 488 // server ----------- acquire inbound credential handle 489 CredHandle phServerCredential = new CredHandle(); 490 TimeStamp ptsServerExpiry = new TimeStamp(); 491 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 492 null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, 493 null, phServerCredential, ptsServerExpiry)); 494 // server ----------- security context 495 CtxtHandle phServerContext = new CtxtHandle(); 496 ManagedSecBufferDesc pbServerToken = null; 497 IntByReference pfServerContextAttr = new IntByReference(); 498 int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; 499 int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; 500 do { 501 // client ----------- initialize security context, produce a client token 502 // client token returned is always new 503 ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 504 if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 505 // server token is empty the first time 506 ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null 507 ? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes()); 508 clientRc = Secur32.INSTANCE.InitializeSecurityContext( 509 phClientCredential, 510 phClientContext.isNull() ? null : phClientContext, 511 Advapi32Util.getUserName(), 512 Sspi.ISC_REQ_CONNECTION | Sspi.ISC_REQ_CONFIDENTIALITY, 513 0, 514 Sspi.SECURITY_NATIVE_DREP, 515 pbServerTokenCopy, 516 0, 517 phClientContext, 518 pbClientToken, 519 pfClientContextAttr, 520 null); 521 assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); 522 } 523 // server ----------- accept security context, produce a server token 524 if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 525 pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 526 ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes()); 527 serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, 528 phServerContext.isNull() ? null : phServerContext, 529 pbClientTokenByValue, 530 Sspi.ISC_REQ_CONNECTION | Sspi.ISC_REQ_CONFIDENTIALITY, 531 Sspi.SECURITY_NATIVE_DREP, 532 phServerContext, 533 pbServerToken, 534 pfServerContextAttr, 535 ptsServerExpiry); 536 assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); 537 } 538 } while (serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); 539 540 assertTrue((pfServerContextAttr.getValue() & Sspi.ISC_REQ_CONFIDENTIALITY) == Sspi.ISC_REQ_CONFIDENTIALITY); 541 assertTrue((pfClientContextAttr.getValue() & Sspi.ISC_REQ_CONFIDENTIALITY) == Sspi.ISC_REQ_CONFIDENTIALITY); 542 543 // Fetch size limits for crypto functions 544 SecPkgContext_Sizes sizes = new SecPkgContext_Sizes(); 545 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.QueryContextAttributes(phClientContext, Sspi.SECPKG_ATTR_SIZES, sizes)); 546 547 // Create sample input data 548 byte[] inputData = "Hallo Welt".getBytes(Charset.forName("ASCII")); 549 550 // Do encryption, buffer 0 holds meta data, buffer 1 holds the 551 // clear text data on input and the encrypted data on output. 552 // Uses the phClientContext 553 ManagedSecBufferDesc encryptBuffers = new ManagedSecBufferDesc(2); 554 555 Memory tokenMemory = new Memory(sizes.cbSecurityTrailer); 556 Memory dataMemory = new Memory(inputData.length); 557 dataMemory.write(0, inputData, 0, inputData.length); 558 559 encryptBuffers.getBuffer(0).BufferType = Sspi.SECBUFFER_TOKEN; 560 encryptBuffers.getBuffer(0).cbBuffer = (int) tokenMemory.size(); 561 encryptBuffers.getBuffer(0).pvBuffer = tokenMemory; 562 encryptBuffers.getBuffer(1).BufferType = Sspi.SECBUFFER_DATA; 563 encryptBuffers.getBuffer(1).cbBuffer = (int) dataMemory.size(); 564 encryptBuffers.getBuffer(1).pvBuffer = dataMemory; 565 566 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.EncryptMessage(phClientContext, 0, encryptBuffers, 0)); 567 568 byte[] encryptedTokenData = encryptBuffers.getBuffer(0).getBytes(); 569 byte[] encryptedData = encryptBuffers.getBuffer(1).getBytes(); 570 571 assertNotNull(encryptedTokenData); 572 assertNotNull(encryptedData); 573 assertTrue(encryptedTokenData.length > 0); 574 assertTrue(encryptedData.length > 0); 575 assertFalse(Arrays.equals(inputData, encryptedData)); 576 577 // Do decryption of data with the pfServerContextAttr 578 ManagedSecBufferDesc decryptBuffers = new ManagedSecBufferDesc(2); 579 580 Memory decryptTokenMemory = new Memory(encryptedTokenData.length); 581 decryptTokenMemory.write(0, encryptedTokenData, 0, encryptedTokenData.length); 582 Memory decryptDataMemory = new Memory(encryptedData.length); 583 decryptDataMemory.write(0, encryptedData, 0, encryptedData.length); 584 585 decryptBuffers.getBuffer(0).BufferType = Sspi.SECBUFFER_TOKEN; 586 decryptBuffers.getBuffer(0).cbBuffer = (int) decryptTokenMemory.size(); 587 decryptBuffers.getBuffer(0).pvBuffer = decryptTokenMemory; 588 decryptBuffers.getBuffer(1).BufferType = Sspi.SECBUFFER_DATA; 589 decryptBuffers.getBuffer(1).cbBuffer = (int) decryptDataMemory.size(); 590 decryptBuffers.getBuffer(1).pvBuffer = decryptDataMemory; 591 592 IntByReference qosResult = new IntByReference(); 593 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DecryptMessage(phServerContext, decryptBuffers, 0, qosResult)); 594 595 byte[] decryptMessageResult = decryptBuffers.getBuffer(1).getBytes(); 596 assertTrue(Arrays.equals(inputData, decryptMessageResult)); 597 598 // Modify message and retry decryption. Decryption is expected to be 599 // refused and the buffers should be untouched. 600 // Modification is done by injecting a NULL byte into the beginning of 601 // the message 602 603 ManagedSecBufferDesc decryptBuffers2 = new ManagedSecBufferDesc(2); 604 605 Memory decryptTokenMemory2 = new Memory(encryptedTokenData.length); 606 decryptTokenMemory2.write(0, encryptedTokenData, 0, encryptedTokenData.length); 607 Memory decryptDataMemory2 = new Memory(encryptedData.length + 1); 608 decryptDataMemory2.write(1, encryptedData, 0, encryptedData.length); 609 610 decryptBuffers2.getBuffer(0).BufferType = Sspi.SECBUFFER_TOKEN; 611 decryptBuffers2.getBuffer(0).cbBuffer = (int) decryptTokenMemory2.size(); 612 decryptBuffers2.getBuffer(0).pvBuffer = decryptTokenMemory2; 613 decryptBuffers2.getBuffer(1).BufferType = Sspi.SECBUFFER_DATA; 614 decryptBuffers2.getBuffer(1).cbBuffer = (int) decryptDataMemory2.size(); 615 decryptBuffers2.getBuffer(1).pvBuffer = decryptDataMemory2; 616 617 assertEquals(W32Errors.SEC_E_MESSAGE_ALTERED, Secur32.INSTANCE.DecryptMessage(phServerContext, decryptBuffers2, 0, qosResult)); 618 619 // release server context 620 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 621 phServerContext)); 622 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 623 phServerCredential)); 624 // release client context 625 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 626 phClientContext)); 627 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 628 phClientCredential)); 629 } 630 testMakeVerifySignature()631 public void testMakeVerifySignature() { 632 // client ----------- acquire outbound credential handle 633 CredHandle phClientCredential = new CredHandle(); 634 TimeStamp ptsClientExpiry = new TimeStamp(); 635 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 636 null, "Negotiate", Sspi.SECPKG_CRED_OUTBOUND, null, null, null, 637 null, phClientCredential, ptsClientExpiry)); 638 // client ----------- security context 639 CtxtHandle phClientContext = new CtxtHandle(); 640 IntByReference pfClientContextAttr = new IntByReference(); 641 // server ----------- acquire inbound credential handle 642 CredHandle phServerCredential = new CredHandle(); 643 TimeStamp ptsServerExpiry = new TimeStamp(); 644 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.AcquireCredentialsHandle( 645 null, "Negotiate", Sspi.SECPKG_CRED_INBOUND, null, null, null, 646 null, phServerCredential, ptsServerExpiry)); 647 // server ----------- security context 648 CtxtHandle phServerContext = new CtxtHandle(); 649 ManagedSecBufferDesc pbServerToken = null; 650 IntByReference pfServerContextAttr = new IntByReference(); 651 int clientRc = W32Errors.SEC_I_CONTINUE_NEEDED; 652 int serverRc = W32Errors.SEC_I_CONTINUE_NEEDED; 653 do { 654 // client ----------- initialize security context, produce a client token 655 // client token returned is always new 656 ManagedSecBufferDesc pbClientToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 657 if (clientRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 658 // server token is empty the first time 659 ManagedSecBufferDesc pbServerTokenCopy = pbServerToken == null 660 ? null : new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbServerToken.getBuffer(0).getBytes()); 661 clientRc = Secur32.INSTANCE.InitializeSecurityContext( 662 phClientCredential, 663 phClientContext.isNull() ? null : phClientContext, 664 Advapi32Util.getUserName(), 665 Sspi.ISC_REQ_CONNECTION | Sspi.ISC_REQ_CONFIDENTIALITY, 666 0, 667 Sspi.SECURITY_NATIVE_DREP, 668 pbServerTokenCopy, 669 0, 670 phClientContext, 671 pbClientToken, 672 pfClientContextAttr, 673 null); 674 assertTrue(clientRc == W32Errors.SEC_I_CONTINUE_NEEDED || clientRc == W32Errors.SEC_E_OK); 675 } 676 // server ----------- accept security context, produce a server token 677 if (serverRc == W32Errors.SEC_I_CONTINUE_NEEDED) { 678 pbServerToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); 679 ManagedSecBufferDesc pbClientTokenByValue = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN, pbClientToken.getBuffer(0).getBytes()); 680 serverRc = Secur32.INSTANCE.AcceptSecurityContext(phServerCredential, 681 phServerContext.isNull() ? null : phServerContext, 682 pbClientTokenByValue, 683 Sspi.ISC_REQ_CONNECTION | Sspi.ISC_REQ_CONFIDENTIALITY, 684 Sspi.SECURITY_NATIVE_DREP, 685 phServerContext, 686 pbServerToken, 687 pfServerContextAttr, 688 ptsServerExpiry); 689 assertTrue(serverRc == W32Errors.SEC_I_CONTINUE_NEEDED || serverRc == W32Errors.SEC_E_OK); 690 } 691 } while(serverRc != W32Errors.SEC_E_OK || clientRc != W32Errors.SEC_E_OK); 692 693 assertTrue((pfServerContextAttr.getValue() & Sspi.ISC_REQ_CONFIDENTIALITY) == Sspi.ISC_REQ_CONFIDENTIALITY); 694 assertTrue((pfClientContextAttr.getValue() & Sspi.ISC_REQ_CONFIDENTIALITY) == Sspi.ISC_REQ_CONFIDENTIALITY); 695 696 // Fetch size limits for crypto functions 697 SecPkgContext_Sizes sizes = new SecPkgContext_Sizes(); 698 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.QueryContextAttributes(phClientContext, Sspi.SECPKG_ATTR_SIZES, sizes)); 699 700 // Create sample input data 701 byte[] inputData = "Hallo Welt".getBytes(Charset.forName("ASCII")); 702 703 // Make signature, buffer 0 holds signature data, buffer 1 holds the 704 // clear text data 705 ManagedSecBufferDesc signingBuffers = new ManagedSecBufferDesc(2); 706 707 Memory tokenMemory = new Memory(sizes.cbMaxSignature); 708 Memory dataMemory = new Memory(inputData.length); 709 dataMemory.write(0, inputData, 0, inputData.length); 710 711 signingBuffers.getBuffer(0).BufferType = Sspi.SECBUFFER_TOKEN; 712 signingBuffers.getBuffer(0).cbBuffer = (int) tokenMemory.size(); 713 signingBuffers.getBuffer(0).pvBuffer = tokenMemory; 714 signingBuffers.getBuffer(1).BufferType = Sspi.SECBUFFER_DATA; 715 signingBuffers.getBuffer(1).cbBuffer = (int) dataMemory.size(); 716 signingBuffers.getBuffer(1).pvBuffer = dataMemory; 717 718 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.MakeSignature(phClientContext, 0, signingBuffers, 0)); 719 720 byte[] signingData = signingBuffers.getBuffer(0).getBytes(); 721 byte[] signedData = signingBuffers.getBuffer(1).getBytes(); 722 723 assertNotNull(signingData); 724 assertNotNull(signedData); 725 assertTrue(signingData.length > 0); 726 assertTrue(signedData.length > 0); 727 assertTrue(Arrays.equals(inputData, signedData)); 728 729 // Do verification of data with the pfServerContextAttr 730 ManagedSecBufferDesc verificationBuffers = new ManagedSecBufferDesc(2); 731 732 Memory verificationSigningMemory = new Memory(signingData.length); 733 verificationSigningMemory.write(0, signingData, 0, signingData.length); 734 Memory verificiationSignedMemory = new Memory(signedData.length); 735 verificiationSignedMemory.write(0, signedData, 0, signedData.length); 736 737 verificationBuffers.getBuffer(0).BufferType = Sspi.SECBUFFER_TOKEN; 738 verificationBuffers.getBuffer(0).cbBuffer = (int) verificationSigningMemory.size(); 739 verificationBuffers.getBuffer(0).pvBuffer = verificationSigningMemory; 740 verificationBuffers.getBuffer(1).BufferType = Sspi.SECBUFFER_DATA; 741 verificationBuffers.getBuffer(1).cbBuffer = (int) verificiationSignedMemory.size(); 742 verificationBuffers.getBuffer(1).pvBuffer = verificiationSignedMemory; 743 744 IntByReference qosResult = new IntByReference(); 745 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.VerifySignature(phServerContext, verificationBuffers, 0, qosResult)); 746 747 byte[] decryptMessageResult = verificationBuffers.getBuffer(1).getBytes(); 748 assertTrue(Arrays.equals(inputData, decryptMessageResult)); 749 750 // Modify message and retry decryption. Decryption is expected to be 751 // refused and the buffers should be untouched. 752 // Modification is done by injecting a NULL byte into the beginning of 753 // the message 754 755 ManagedSecBufferDesc verificationBuffers2 = new ManagedSecBufferDesc(2); 756 757 Memory verificationSigingMemory2 = new Memory(signingData.length); 758 verificationSigingMemory2.write(0, signingData, 0, signingData.length); 759 Memory verificationSignedMemory2 = new Memory(signedData.length + 1); 760 verificationSignedMemory2.write(1, signedData, 0, signedData.length); 761 762 verificationBuffers2.getBuffer(0).BufferType = Sspi.SECBUFFER_TOKEN; 763 verificationBuffers2.getBuffer(0).cbBuffer = (int) verificationSigingMemory2.size(); 764 verificationBuffers2.getBuffer(0).pvBuffer = verificationSigingMemory2; 765 verificationBuffers2.getBuffer(1).BufferType = Sspi.SECBUFFER_DATA; 766 verificationBuffers2.getBuffer(1).cbBuffer = (int) verificationSignedMemory2.size(); 767 verificationBuffers2.getBuffer(1).pvBuffer = verificationSignedMemory2; 768 769 qosResult = new IntByReference(); 770 assertEquals(W32Errors.SEC_E_MESSAGE_ALTERED, Secur32.INSTANCE.VerifySignature(phServerContext, verificationBuffers2, 0, qosResult)); 771 772 // release server context 773 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 774 phServerContext)); 775 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 776 phServerCredential)); 777 // release client context 778 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.DeleteSecurityContext( 779 phClientContext)); 780 assertEquals(W32Errors.SEC_E_OK, Secur32.INSTANCE.FreeCredentialsHandle( 781 phClientCredential)); 782 } 783 testCompleteAuthToken()784 public void testCompleteAuthToken() { 785 /* 786 This is not a real test of the function, it just ensures, that it is 787 callable and returns a sane error code. 788 */ 789 int result = Secur32.INSTANCE.CompleteAuthToken(null, null); 790 assertTrue(String.format("Unexpected error code: 0x%08X%n", result), 791 result == WinError.SEC_E_INVALID_HANDLE 792 || result == WinError.SEC_E_INVALID_TOKEN); 793 } 794 } 795