diff --git a/build/WinStd.vcxproj b/build/WinStd.vcxproj
index 1e8085c9..09e03c49 100644
--- a/build/WinStd.vcxproj
+++ b/build/WinStd.vcxproj
@@ -82,6 +82,7 @@
+
diff --git a/build/WinStd.vcxproj.filters b/build/WinStd.vcxproj.filters
index 6136d96a..4080982b 100644
--- a/build/WinStd.vcxproj.filters
+++ b/build/WinStd.vcxproj.filters
@@ -49,5 +49,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/include/WinStd/Cred.h b/include/WinStd/Cred.h
new file mode 100644
index 00000000..f968c261
--- /dev/null
+++ b/include/WinStd/Cred.h
@@ -0,0 +1,270 @@
+/*
+ Copyright 1991-2016 Amebis
+ Copyright 2016 GÉANT
+
+ This file is part of WinStd.
+
+ Setup is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Setup is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Setup. If not, see .
+*/
+
+#include "Common.h"
+
+#include
+
+#include
+
+namespace winstd
+{
+ template struct CredFree_delete;
+ template struct CredFree_delete<_Ty[]>;
+ class credential;
+}
+
+template inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType);
+template inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType);
+template inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials);
+template inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials);
+
+#pragma once
+
+
+namespace winstd
+{
+ /// \addtogroup ATLCryptoAPI
+ /// @{
+
+ ///
+ /// Deleter for unique_ptr using CredFree
+ ///
+ template struct CredFree_delete
+ {
+ typedef CredFree_delete<_Ty> _Myt;
+
+ ///
+ /// Default construct
+ ///
+ CredFree_delete() {}
+
+ ///
+ /// Construct from another CredFree_delete
+ ///
+ template CredFree_delete(const CredFree_delete<_Ty2>&) {}
+
+ ///
+ /// Delete a pointer
+ ///
+ void operator()(_Ty *_Ptr) const
+ {
+ CredFree(_Ptr);
+ }
+ };
+
+
+ ///
+ /// Deleter for unique_ptr to array of unknown size using CredFree
+ ///
+ template struct CredFree_delete<_Ty[]>
+ {
+ typedef CredFree_delete<_Ty> _Myt;
+
+ ///
+ /// Default construct
+ ///
+ CredFree_delete() {}
+
+ ///
+ /// Delete a pointer
+ ///
+ void operator()(_Ty *_Ptr) const
+ {
+ CredFree(_Ptr);
+ }
+
+ ///
+ /// Delete a pointer of another type
+ ///
+ template
+ void operator()(_Other *) const
+ {
+ CredFree(_Ptr);
+ }
+ };
+
+
+ ///
+ /// PCREDENTIAL wrapper class
+ ///
+ class credential : public handle
+ {
+ public:
+ ///
+ /// Closes the credential.
+ ///
+ /// \sa [CredFree function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374796.aspx)
+ ///
+ virtual ~credential()
+ {
+ if (m_h)
+ CredFree(m_h);
+ }
+
+ protected:
+ ///
+ /// Closes the credential.
+ ///
+ /// \sa [CredFree function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374796.aspx)
+ ///
+ virtual void free_internal()
+ {
+ CredFree(m_h);
+ }
+ };
+
+ /// @}
+}
+
+
+///
+/// \defgroup WinStdCryptoAPI Cryptography API
+/// Integrates WinStd classes with Microsoft Cryptography API
+///
+/// @{
+
+inline BOOL CredEnumerate(_In_ LPCTSTR Filter, _In_ DWORD Flags, _Out_ DWORD *Count, _Out_ std::unique_ptr > &cCredentials)
+{
+ PCREDENTIAL *pCredentials;
+ if (CredEnumerate(Filter, Flags, Count, &pCredentials)) {
+ cCredentials.swap(std::unique_ptr >(pCredentials));
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+///
+/// Encrypts the specified credentials so that only the current security context can decrypt them.
+///
+/// \sa [CredProtect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374803.aspx)
+///
+template
+inline BOOL CredProtectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
+{
+ _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
+ DWORD dwSize = _countof(buf);
+
+ // Try with the stack buffer first.
+ if (CredProtectA(fAsSelf, (LPSTR)pszCredentials, cchCredentials, buf, &dwSize, ProtectionType)) {
+ // Copy from stack.
+ sProtectedCredentials.assign(buf, dwSize - 1);
+ return TRUE;
+ } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ // Allocate on heap and retry.
+ auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
+ if (CredProtectA(fAsSelf, (LPSTR)pszCredentials, cchCredentials, buf.get(), &dwSize, ProtectionType)) {
+ sProtectedCredentials.assign(buf.get(), dwSize - 1);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+///
+/// Encrypts the specified credentials so that only the current security context can decrypt them.
+///
+/// \sa [CredProtect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374803.aspx)
+///
+template
+inline BOOL CredProtectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sProtectedCredentials, _Out_ CRED_PROTECTION_TYPE *ProtectionType)
+{
+ _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
+ DWORD dwSize = _countof(buf);
+
+ // Try with the stack buffer first.
+ if (CredProtectW(fAsSelf, (LPWSTR)pszCredentials, cchCredentials, buf, &dwSize, ProtectionType)) {
+ // Copy from stack.
+ sProtectedCredentials.assign(buf, dwSize - 1);
+ return TRUE;
+ } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ // Allocate on heap and retry.
+ auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
+ if (CredProtectW(fAsSelf, (LPWSTR)pszCredentials, cchCredentials, buf.get(), &dwSize, ProtectionType)) {
+ sProtectedCredentials.assign(buf.get(), dwSize - 1);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+///
+/// Decrypts credentials that were previously encrypted by using the CredProtect function.
+///
+/// \sa [CredUnprotect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375186.aspx)
+///
+template
+inline BOOL CredUnprotectA(_In_ BOOL fAsSelf, _In_ LPCSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials)
+{
+ _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
+ DWORD dwSize = _countof(buf);
+
+ // Try with the stack buffer first.
+ if (CredUnprotectA(fAsSelf, (LPSTR)pszProtectedCredentials, cchCredentials, buf, &dwSize)) {
+ // Copy from stack.
+ sCredentials.assign(buf, dwSize);
+ return TRUE;
+ } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ // Allocate on heap and retry.
+ auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
+ if (CredUnprotectA(fAsSelf, (LPSTR)pszProtectedCredentials, cchCredentials, buf.get(), &dwSize)) {
+ sCredentials.assign(buf.get(), dwSize);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+///
+/// Decrypts credentials that were previously encrypted by using the CredProtect function.
+///
+/// \sa [CredUnprotect function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa375186.aspx)
+///
+template
+inline BOOL CredUnprotectW(_In_ BOOL fAsSelf, _In_ LPCWSTR pszProtectedCredentials, _In_ DWORD cchCredentials, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sCredentials)
+{
+ _Elem buf[WINSTD_STACK_BUFFER_BYTES/sizeof(_Elem)];
+ DWORD dwSize = _countof(buf);
+
+ // Try with the stack buffer first.
+ if (CredUnprotectW(fAsSelf, (LPWSTR)pszProtectedCredentials, cchCredentials, buf, &dwSize)) {
+ // Copy from stack.
+ sCredentials.assign(buf, dwSize);
+ return TRUE;
+ } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ // Allocate on heap and retry.
+ auto buf = std::unique_ptr<_Elem[]>(new _Elem[dwSize]);
+ if (CredUnprotectW(fAsSelf, (LPWSTR)pszProtectedCredentials, cchCredentials, buf.get(), &dwSize)) {
+ sCredentials.assign(buf.get(), dwSize);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/// @}
diff --git a/src/StdAfx.h b/src/StdAfx.h
index 56836c6b..82383df9 100644
--- a/src/StdAfx.h
+++ b/src/StdAfx.h
@@ -21,6 +21,7 @@
#pragma once
#include "../include/WinStd/Base64.h"
+#include "../include/WinStd/Cred.h"
#include "../include/WinStd/Crypt.h"
#include "../include/WinStd/EAP.h"
#include "../include/WinStd/Common.h"