/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.internal.util.jna;
import org.tmatesoft.svn.core.internal.util.SVNBase64;
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import com.sun.jna.NativeLong;
import com.sun.jna.WString;
/**
* @version 1.3
* @author TMate Software Ltd.
*/
class SVNWinCrypt {
public static char[] decrypt(char[] encryptedData) {
if (encryptedData == null) {
return null;
}
ISVNWinCryptLibrary library = JNALibraryLoader.getWinCryptLibrary();
if (library == null) {
return null;
}
byte[] buffer = new byte[encryptedData.length];
encryptedData = SVNBase64.normalizeBase64(encryptedData);
int decodedBytes = SVNBase64.base64ToByteArray(encryptedData, buffer);
byte[] decodedBuffer = new byte[decodedBytes];
System.arraycopy(buffer, 0, decodedBuffer, 0, decodedBytes);
SVNEncodingUtil.clearArray(buffer);
ISVNWinCryptLibrary.DATA_BLOB dataIn = null;
ISVNWinCryptLibrary.DATA_BLOB dataOut = null;
try {
dataIn = new ISVNWinCryptLibrary.DATA_BLOB(decodedBuffer);
dataIn.write();
dataOut = new ISVNWinCryptLibrary.DATA_BLOB(null);
dataOut.write();
synchronized (library) {
boolean ok = library.CryptUnprotectData(
dataIn.getPointer(),
null, null, null, null, new NativeLong(1),
dataOut.getPointer());
if (!ok) {
return encryptedData;
}
dataOut.read();
}
if (dataOut.cbSize == null || dataOut.cbSize.intValue() < 0) {
return null;
}
byte[] decryptedData = new byte[dataOut.cbSize.intValue()];
dataOut.cbData.read(0, decryptedData, 0, decryptedData.length);
return SVNEncodingUtil.getChars(decryptedData, 0, decryptedData.length, "UTF-8");
} catch (Throwable th) {
return null;
} finally {
ISVNKernel32Library kernel = JNALibraryLoader.getKernelLibrary();
if (kernel != null) {
try {
synchronized (kernel) {
if (dataOut != null) {
kernel.LocalFree(dataOut.cbData);
}
}
} catch (Throwable th) {
//
}
}
}
}
public static char[] encrypt(char[] rawData) {
if (rawData == null) {
return null;
}
ISVNWinCryptLibrary library = JNALibraryLoader.getWinCryptLibrary();
if (library == null) {
return rawData;
}
ISVNWinCryptLibrary.DATA_BLOB dataIn = null;
ISVNWinCryptLibrary.DATA_BLOB dataOut = null;
try {
dataIn = new ISVNWinCryptLibrary.DATA_BLOB(SVNEncodingUtil.getBytes(rawData, "UTF-8"));
dataIn.write();
dataOut = new ISVNWinCryptLibrary.DATA_BLOB(null);
dataOut.write();
synchronized (library) {
boolean ok = library.CryptProtectData(
dataIn.getPointer(),
new WString("auth_svn.simple.wincrypt"),
null, null, null, new NativeLong(1),
dataOut.getPointer());
if (!ok) {
return rawData;
}
dataOut.read();
}
if (dataOut.cbSize == null || dataOut.cbSize.intValue() <= 0) {
return rawData;
}
byte[] encryptedData = new byte[dataOut.cbSize.intValue()];
dataOut.cbData.read(0, encryptedData, 0, encryptedData.length);
return SVNBase64.byteArrayToBase64(encryptedData).toCharArray();
} catch (Throwable th) {
return rawData;
} finally {
ISVNKernel32Library kernel = JNALibraryLoader.getKernelLibrary();
if (kernel != null) {
try {
synchronized (kernel) {
if (dataOut != null) {
kernel.LocalFree(dataOut.cbData);
}
}
} catch (Throwable th) {
}
}
}
}
public synchronized static boolean isEnabled() {
return SVNFileUtil.isWindows && JNALibraryLoader.getWinCryptLibrary() != null;
}
}