2 * security.c: Security internal calls
5 * Sebastien Pouliot <sebastien@ximian.com>
7 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
8 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
15 #include <mono/metadata/assembly.h>
16 #include <mono/metadata/appdomain.h>
17 #include <mono/metadata/image.h>
18 #include <mono/metadata/exception.h>
19 #include <mono/metadata/object-internals.h>
20 #include <mono/metadata/metadata-internals.h>
21 #include <mono/metadata/security.h>
22 #include <mono/io-layer/io-layer.h>
23 #include <mono/utils/strenc.h>
30 #ifndef PROTECTED_DACL_SECURITY_INFORMATION
31 #define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000L
45 #include <sys/types.h>
52 #ifndef HAVE_GETGRGID_R
53 #warning Non-thread safe getgrgid being used!
55 #ifndef HAVE_GETGRNAM_R
56 #warning Non-thread safe getgrnam being used!
58 #ifndef HAVE_GETPWNAM_R
59 #warning Non-thread safe getpwnam being used!
61 #ifndef HAVE_GETPWUID_R
62 #warning Non-thread safe getpwuid being used!
65 #endif /* defined(__GNUC__) */
67 #endif /* not HOST_WIN32 */
70 /* internal functions - reuse driven */
74 /* ask a server to translate a SID into a textual representation */
76 GetSidName (gunichar2
*server
, PSID sid
, gint32
*size
)
78 gunichar2
*uniname
= NULL
;
81 SID_NAME_USE peUse
; /* out */
83 LookupAccountSid (server
, sid
, NULL
, &cchName
, NULL
,
86 if ((cchName
> 0) && (cchDomain
> 0)) {
87 gunichar2
*user
= g_malloc0 ((cchName
+ 1) * 2);
88 gunichar2
*domain
= g_malloc0 ((cchDomain
+ 1) * 2);
90 LookupAccountSid (server
, sid
, user
, &cchName
, domain
,
95 /* domain/machine name included (+ sepearator) */
96 *size
= cchName
+ cchDomain
+ 1;
97 uniname
= g_malloc0 ((*size
+ 1) * 2);
98 memcpy (uniname
, domain
, cchDomain
* 2);
99 *(uniname
+ cchDomain
) = '\\';
100 memcpy (uniname
+ cchDomain
+ 1, user
, cchName
* 2);
104 /* no domain / machine */
110 /* nothing -> return NULL */
121 #else /* not HOST_WIN32 */
123 #define MONO_SYSCONF_DEFAULT_SIZE ((size_t) 1024)
126 * Ensure we always get a valid (usable) value from sysconf.
127 * In case of error, we return the default value.
129 static size_t mono_sysconf (int name
)
131 size_t size
= (size_t) sysconf (name
);
133 return (size
== -1) ? MONO_SYSCONF_DEFAULT_SIZE
: size
;
138 GetTokenName (uid_t uid
)
142 #ifdef HAVE_GETPWUID_R
148 struct passwd
*p
= NULL
;
151 #ifdef HAVE_GETPWUID_R
152 #ifdef _SC_GETPW_R_SIZE_MAX
153 fbufsize
= mono_sysconf (_SC_GETPW_R_SIZE_MAX
);
155 fbufsize
= MONO_SYSCONF_DEFAULT_SIZE
;
157 fbuf
= (gchar
*)g_malloc0 (fbufsize
);
158 retval
= getpwuid_r (uid
, &pwd
, fbuf
, fbufsize
, &p
);
159 result
= ((retval
== 0) && (p
== &pwd
));
161 /* default to non thread-safe but posix compliant function */
163 result
= (p
!= NULL
);
167 uname
= g_strdup (p
->pw_name
);
170 #ifdef HAVE_GETPWUID_R
179 IsMemberInList (uid_t user
, struct group
*g
)
181 gboolean result
= FALSE
;
182 gchar
*utf8_username
= GetTokenName (user
);
188 gchar
**users
= g
->gr_mem
;
192 if (strcmp (utf8_username
, u
) == 0) {
200 g_free (utf8_username
);
206 IsDefaultGroup (uid_t user
, gid_t group
)
208 #ifdef HAVE_GETPWUID_R
214 struct passwd
*p
= NULL
;
217 #ifdef HAVE_GETPWUID_R
218 #ifdef _SC_GETPW_R_SIZE_MAX
219 fbufsize
= mono_sysconf (_SC_GETPW_R_SIZE_MAX
);
221 fbufsize
= MONO_SYSCONF_DEFAULT_SIZE
;
224 fbuf
= (gchar
*)g_malloc0 (fbufsize
);
225 retval
= getpwuid_r (user
, &pwd
, fbuf
, fbufsize
, &p
);
226 result
= ((retval
== 0) && (p
== &pwd
));
228 /* default to non thread-safe but posix compliant function */
230 result
= (p
!= NULL
);
234 result
= (p
->pw_gid
== group
);
237 #ifdef HAVE_GETPWUID_R
246 IsMemberOf (gid_t user
, struct group
*g
)
251 /* is it the user default group */
252 if (IsDefaultGroup (user
, g
->gr_gid
))
255 /* is the user in the group list */
256 return IsMemberInList (user
, g
);
265 /* System.Security.Principal.WindowsIdentity */
269 ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (void)
271 gpointer token
= NULL
;
274 /* Note: This isn't a copy of the Token - we must not close it!!!
275 * http://www.develop.com/kbrown/book/html/whatis_windowsprincipal.html
278 /* thread may be impersonating somebody */
279 if (OpenThreadToken (GetCurrentThread (), TOKEN_QUERY
, 1, &token
) == 0) {
280 /* if not take the process identity */
281 OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY
, &token
);
284 token
= GINT_TO_POINTER (geteuid ());
291 ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName (gpointer token
)
294 MonoString
*result
= NULL
;
295 gunichar2
*uniname
= NULL
;
298 mono_error_init (&error
);
300 GetTokenInformation (token
, TokenUser
, NULL
, size
, (PDWORD
)&size
);
302 TOKEN_USER
*tu
= g_malloc0 (size
);
303 if (GetTokenInformation (token
, TokenUser
, tu
, size
, (PDWORD
)&size
)) {
304 uniname
= GetSidName (NULL
, tu
->User
.Sid
, &size
);
309 gchar
*uname
= GetTokenName ((uid_t
) GPOINTER_TO_INT (token
));
312 size
= strlen (uname
);
313 uniname
= g_utf8_to_utf16 (uname
, size
, NULL
, NULL
, NULL
);
316 #endif /* HOST_WIN32 */
319 result
= mono_string_new_utf16_checked (mono_domain_get (), uniname
, size
, &error
);
322 result
= mono_string_new (mono_domain_get (), "");
327 mono_error_set_pending_exception (&error
);
333 ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken (MonoString
*username
)
336 gpointer token
= NULL
;
338 /* TODO: MS has something like this working in Windows 2003 (client and
339 * server) but works only for domain accounts (so it's quite limiting).
340 * http://www.develop.com/kbrown/book/html/howto_logonuser.html
342 g_warning ("Unsupported on Win32 (anyway requires W2K3 minimum)");
344 #else /* HOST_WIN32*/
346 #ifdef HAVE_GETPWNAM_R
352 gpointer token
= (gpointer
) -2;
357 utf8_name
= mono_unicode_to_external (mono_string_chars (username
));
359 #ifdef HAVE_GETPWNAM_R
360 #ifdef _SC_GETPW_R_SIZE_MAX
361 fbufsize
= mono_sysconf (_SC_GETPW_R_SIZE_MAX
);
363 fbufsize
= MONO_SYSCONF_DEFAULT_SIZE
;
366 fbuf
= (gchar
*)g_malloc0 (fbufsize
);
367 retval
= getpwnam_r (utf8_name
, &pwd
, fbuf
, fbufsize
, &p
);
368 result
= ((retval
== 0) && (p
== &pwd
));
370 /* default to non thread-safe but posix compliant function */
371 p
= getpwnam (utf8_name
);
372 result
= (p
!= NULL
);
376 token
= GINT_TO_POINTER (p
->pw_uid
);
379 #ifdef HAVE_GETPWNAM_R
388 /* http://www.dotnet247.com/247reference/msgs/39/195403.aspx
389 // internal static string[] WindowsIdentity._GetRoles (IntPtr token)
392 ves_icall_System_Security_Principal_WindowsIdentity_GetRoles (gpointer token
)
395 MonoArray
*array
= NULL
;
396 MonoDomain
*domain
= mono_domain_get ();
400 GetTokenInformation (token
, TokenGroups
, NULL
, size
, (PDWORD
)&size
);
402 TOKEN_GROUPS
*tg
= g_malloc0 (size
);
403 if (GetTokenInformation (token
, TokenGroups
, tg
, size
, (PDWORD
)&size
)) {
405 int num
= tg
->GroupCount
;
407 array
= mono_array_new_checked (domain
, mono_get_string_class (), num
, &error
);
408 if (mono_error_set_pending_exception (&error
)) {
413 for (i
=0; i
< num
; i
++) {
415 gunichar2
*uniname
= GetSidName (NULL
, tg
->Groups
[i
].Sid
, &size
);
418 MonoString
*str
= mono_string_new_utf16_checked (domain
, uniname
, size
, &error
);
419 if (!is_ok (&error
)) {
422 mono_error_set_pending_exception (&error
);
425 mono_array_setref (array
, i
, str
);
433 /* POSIX-compliant systems should use IsMemberOfGroupId or IsMemberOfGroupName */
434 g_warning ("WindowsIdentity._GetRoles should never be called on POSIX");
437 /* return empty array of string, i.e. string [0] */
438 array
= mono_array_new_checked (domain
, mono_get_string_class (), 0, &error
);
439 mono_error_set_pending_exception (&error
);
445 /* System.Security.Principal.WindowsImpersonationContext */
449 ves_icall_System_Security_Principal_WindowsImpersonationContext_CloseToken (gpointer token
)
451 gboolean result
= TRUE
;
454 result
= (CloseHandle (token
) != 0);
461 ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken (gpointer token
)
463 gpointer dupe
= NULL
;
466 if (DuplicateToken (token
, SecurityImpersonation
, &dupe
) == 0) {
477 ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken (gpointer token
)
479 /* Posix version implemented in /mono/mono/io-layer/security.c */
480 return (ImpersonateLoggedOnUser (token
) != 0);
485 ves_icall_System_Security_Principal_WindowsImpersonationContext_RevertToSelf (void)
487 /* Posix version implemented in /mono/mono/io-layer/security.c */
488 return (RevertToSelf () != 0);
492 /* System.Security.Principal.WindowsPrincipal */
495 ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId (gpointer user
, gpointer group
)
497 gboolean result
= FALSE
;
500 /* The convertion from an ID to a string is done in managed code for Windows */
501 g_warning ("IsMemberOfGroupId should never be called on Win32");
503 #else /* HOST_WIN32 */
505 #ifdef HAVE_GETGRGID_R
511 struct group
*g
= NULL
;
513 #ifdef HAVE_GETGRGID_R
514 #ifdef _SC_GETGR_R_SIZE_MAX
515 fbufsize
= mono_sysconf (_SC_GETGR_R_SIZE_MAX
);
517 fbufsize
= MONO_SYSCONF_DEFAULT_SIZE
;
519 fbuf
= (gchar
*)g_malloc0 (fbufsize
);
520 retval
= getgrgid_r ((gid_t
) GPOINTER_TO_INT (group
), &grp
, fbuf
, fbufsize
, &g
);
521 result
= ((retval
== 0) && (g
== &grp
));
523 /* default to non thread-safe but posix compliant function */
524 g
= getgrgid ((gid_t
) GPOINTER_TO_INT (group
));
525 result
= (g
!= NULL
);
529 result
= IsMemberOf ((uid_t
) GPOINTER_TO_INT (user
), g
);
532 #ifdef HAVE_GETGRGID_R
536 #endif /* HOST_WIN32 */
543 ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName (gpointer user
, MonoString
*group
)
545 gboolean result
= FALSE
;
548 /* Windows version use a cache built using WindowsIdentity._GetRoles */
549 g_warning ("IsMemberOfGroupName should never be called on Win32");
551 #else /* HOST_WIN32 */
552 gchar
*utf8_groupname
;
554 utf8_groupname
= mono_unicode_to_external (mono_string_chars (group
));
555 if (utf8_groupname
) {
556 struct group
*g
= NULL
;
557 #ifdef HAVE_GETGRNAM_R
561 #ifdef _SC_GETGR_R_SIZE_MAX
562 size_t fbufsize
= mono_sysconf (_SC_GETGR_R_SIZE_MAX
);
564 size_t fbufsize
= MONO_SYSCONF_DEFAULT_SIZE
;
566 fbuf
= (gchar
*)g_malloc0 (fbufsize
);
567 retval
= getgrnam_r (utf8_groupname
, &grp
, fbuf
, fbufsize
, &g
);
568 result
= ((retval
== 0) && (g
== &grp
));
570 /* default to non thread-safe but posix compliant function */
571 g
= getgrnam (utf8_groupname
);
572 result
= (g
!= NULL
);
576 result
= IsMemberOf ((uid_t
) GPOINTER_TO_INT (user
), g
);
579 #ifdef HAVE_GETGRNAM_R
582 g_free (utf8_groupname
);
584 #endif /* HOST_WIN32 */
590 /* Mono.Security.Cryptography IO related internal calls */
595 GetAdministratorsSid (void)
597 SID_IDENTIFIER_AUTHORITY admins
= SECURITY_NT_AUTHORITY
;
599 if (!AllocateAndInitializeSid (&admins
, 2, SECURITY_BUILTIN_DOMAIN_RID
,
600 DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0, &pSid
))
602 /* Note: this SID must be freed with FreeSid () */
608 GetEveryoneSid (void)
610 SID_IDENTIFIER_AUTHORITY everyone
= SECURITY_WORLD_SID_AUTHORITY
;
612 if (!AllocateAndInitializeSid (&everyone
, 1, SECURITY_WORLD_RID
, 0, 0, 0, 0, 0, 0, 0, &pSid
))
614 /* Note: this SID must be freed with FreeSid () */
620 GetCurrentUserSid (void)
624 gpointer token
= ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken ();
626 GetTokenInformation (token
, TokenUser
, NULL
, size
, (PDWORD
)&size
);
628 TOKEN_USER
*tu
= g_malloc0 (size
);
629 if (GetTokenInformation (token
, TokenUser
, tu
, size
, (PDWORD
)&size
)) {
630 DWORD length
= GetLengthSid (tu
->User
.Sid
);
631 sid
= (PSID
) g_malloc0 (length
);
632 if (!CopySid (length
, sid
, tu
->User
.Sid
)) {
639 /* Note: this SID must be freed with g_free () */
645 GetRightsFromSid (PSID sid
, PACL acl
)
647 ACCESS_MASK rights
= 0;
650 BuildTrusteeWithSidW (&trustee
, sid
);
651 if (GetEffectiveRightsFromAcl (acl
, &trustee
, &rights
) != ERROR_SUCCESS
)
659 IsMachineProtected (gunichar2
*path
)
661 gboolean success
= FALSE
;
663 PSID pEveryoneSid
= NULL
;
665 DWORD dwRes
= GetNamedSecurityInfoW (path
, SE_FILE_OBJECT
, DACL_SECURITY_INFORMATION
, NULL
, NULL
, &pDACL
, NULL
, NULL
);
666 if (dwRes
!= ERROR_SUCCESS
)
669 /* We check that Everyone is still limited to READ-ONLY -
670 but not if new entries have been added by an Administrator */
672 pEveryoneSid
= GetEveryoneSid ();
674 ACCESS_MASK rights
= GetRightsFromSid (pEveryoneSid
, pDACL
);
675 /* http://msdn.microsoft.com/library/en-us/security/security/generic_access_rights.asp?frame=true */
676 success
= (rights
== (READ_CONTROL
| SYNCHRONIZE
| FILE_READ_DATA
| FILE_READ_EA
| FILE_READ_ATTRIBUTES
));
677 FreeSid (pEveryoneSid
);
679 /* Note: we don't need to check our own access -
680 we'll know soon enough when reading the file */
690 IsUserProtected (gunichar2
*path
)
692 gboolean success
= FALSE
;
694 PSID pEveryoneSid
= NULL
;
695 PSECURITY_DESCRIPTOR pSecurityDescriptor
= NULL
;
697 DWORD dwRes
= GetNamedSecurityInfoW (path
, SE_FILE_OBJECT
,
698 DACL_SECURITY_INFORMATION
, NULL
, NULL
, &pDACL
, NULL
, &pSecurityDescriptor
);
699 if (dwRes
!= ERROR_SUCCESS
)
702 /* We check that our original entries in the ACL are in place -
703 but not if new entries have been added by the user */
705 /* Everyone should be denied */
706 pEveryoneSid
= GetEveryoneSid ();
708 ACCESS_MASK rights
= GetRightsFromSid (pEveryoneSid
, pDACL
);
709 success
= (rights
== 0);
710 FreeSid (pEveryoneSid
);
712 /* Note: we don't need to check our own access -
713 we'll know soon enough when reading the file */
715 if (pSecurityDescriptor
)
716 LocalFree (pSecurityDescriptor
);
723 ProtectMachine (gunichar2
*path
)
725 PSID pEveryoneSid
= GetEveryoneSid ();
726 PSID pAdminsSid
= GetAdministratorsSid ();
729 if (pEveryoneSid
&& pAdminsSid
) {
731 EXPLICIT_ACCESS ea
[2];
732 ZeroMemory (&ea
, 2 * sizeof (EXPLICIT_ACCESS
));
734 /* grant all access to the BUILTIN\Administrators group */
735 BuildTrusteeWithSidW (&ea
[0].Trustee
, pAdminsSid
);
736 ea
[0].grfAccessPermissions
= GENERIC_ALL
;
737 ea
[0].grfAccessMode
= SET_ACCESS
;
738 ea
[0].grfInheritance
= SUB_CONTAINERS_AND_OBJECTS_INHERIT
;
739 ea
[0].Trustee
.TrusteeForm
= TRUSTEE_IS_SID
;
740 ea
[0].Trustee
.TrusteeType
= TRUSTEE_IS_WELL_KNOWN_GROUP
;
742 /* read-only access everyone */
743 BuildTrusteeWithSidW (&ea
[1].Trustee
, pEveryoneSid
);
744 ea
[1].grfAccessPermissions
= GENERIC_READ
;
745 ea
[1].grfAccessMode
= SET_ACCESS
;
746 ea
[1].grfInheritance
= SUB_CONTAINERS_AND_OBJECTS_INHERIT
;
747 ea
[1].Trustee
.TrusteeForm
= TRUSTEE_IS_SID
;
748 ea
[1].Trustee
.TrusteeType
= TRUSTEE_IS_WELL_KNOWN_GROUP
;
750 retval
= SetEntriesInAcl (2, ea
, NULL
, &pDACL
);
751 if (retval
== ERROR_SUCCESS
) {
752 /* with PROTECTED_DACL_SECURITY_INFORMATION we */
753 /* remove any existing ACL (like inherited ones) */
754 retval
= SetNamedSecurityInfo (path
, SE_FILE_OBJECT
,
755 DACL_SECURITY_INFORMATION
| PROTECTED_DACL_SECURITY_INFORMATION
,
756 NULL
, NULL
, pDACL
, NULL
);
763 FreeSid (pEveryoneSid
);
765 FreeSid (pAdminsSid
);
766 return (retval
== ERROR_SUCCESS
);
771 ProtectUser (gunichar2
*path
)
775 PSID pCurrentSid
= GetCurrentUserSid ();
779 ZeroMemory (&ea
, sizeof (EXPLICIT_ACCESS
));
781 /* grant exclusive access to the current user */
782 BuildTrusteeWithSidW (&ea
.Trustee
, pCurrentSid
);
783 ea
.grfAccessPermissions
= GENERIC_ALL
;
784 ea
.grfAccessMode
= SET_ACCESS
;
785 ea
.grfInheritance
= SUB_CONTAINERS_AND_OBJECTS_INHERIT
;
786 ea
.Trustee
.TrusteeForm
= TRUSTEE_IS_SID
;
787 ea
.Trustee
.TrusteeType
= TRUSTEE_IS_USER
;
789 retval
= SetEntriesInAcl (1, &ea
, NULL
, &pDACL
);
790 if (retval
== ERROR_SUCCESS
) {
791 /* with PROTECTED_DACL_SECURITY_INFORMATION we
792 remove any existing ACL (like inherited ones) */
793 retval
= SetNamedSecurityInfo (path
, SE_FILE_OBJECT
,
794 DACL_SECURITY_INFORMATION
| PROTECTED_DACL_SECURITY_INFORMATION
,
795 NULL
, NULL
, pDACL
, NULL
);
800 g_free (pCurrentSid
); /* g_malloc0 */
803 return (retval
== ERROR_SUCCESS
);
809 IsProtected (MonoString
*path
, gint32 protection
)
811 gboolean result
= FALSE
;
812 gchar
*utf8_name
= mono_unicode_to_external (mono_string_chars (path
));
815 if (stat (utf8_name
, &st
) == 0) {
816 result
= (((st
.st_mode
& 0777) & protection
) == 0);
825 Protect (MonoString
*path
, gint32 file_mode
, gint32 add_dir_mode
)
827 gboolean result
= FALSE
;
828 gchar
*utf8_name
= mono_unicode_to_external (mono_string_chars (path
));
831 if (stat (utf8_name
, &st
) == 0) {
832 int mode
= file_mode
;
833 if (st
.st_mode
& S_IFDIR
)
834 mode
|= add_dir_mode
;
835 result
= (chmod (utf8_name
, mode
) == 0);
842 #endif /* not HOST_WIN32 */
846 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure (MonoString
*root
)
851 /* ACL are nice... unless you have FAT or other uncivilized filesystem */
852 if (!GetVolumeInformation (mono_string_chars (root
), NULL
, 0, NULL
, NULL
, (LPDWORD
)&flags
, NULL
, 0))
854 return ((flags
& FS_PERSISTENT_ACLS
) == FS_PERSISTENT_ACLS
);
856 /* we assume some kind of security is applicable outside Windows */
863 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsMachineProtected (MonoString
*path
)
865 gboolean ret
= FALSE
;
867 /* no one, but the owner, should have write access to the directory */
869 ret
= IsMachineProtected (mono_string_chars (path
));
871 ret
= IsProtected (path
, (S_IWGRP
| S_IWOTH
));
878 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsUserProtected (MonoString
*path
)
880 gboolean ret
= FALSE
;
882 /* no one, but the user, should have access to the directory */
884 ret
= IsUserProtected (mono_string_chars (path
));
886 ret
= IsProtected (path
, (S_IRGRP
| S_IWGRP
| S_IXGRP
| S_IROTH
| S_IWOTH
| S_IXOTH
));
893 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectMachine (MonoString
*path
)
895 gboolean ret
= FALSE
;
897 /* read/write to owner, read to everyone else */
899 ret
= ProtectMachine (mono_string_chars (path
));
901 ret
= Protect (path
, (S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
), (S_IXUSR
| S_IXGRP
| S_IXOTH
));
908 ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectUser (MonoString
*path
)
910 gboolean ret
= FALSE
;
912 /* read/write to user, no access to everyone else */
914 ret
= ProtectUser (mono_string_chars (path
));
916 ret
= Protect (path
, (S_IRUSR
| S_IWUSR
), S_IXUSR
);
923 * Returns TRUE if there is "something" where the Authenticode signature is
924 * normally located. Returns FALSE is data directory is empty.
926 * Note: Neither the structure nor the signature is verified by this function.
929 ves_icall_System_Security_Policy_Evidence_IsAuthenticodePresent (MonoReflectionAssembly
*refass
)
931 if (refass
&& refass
->assembly
&& refass
->assembly
->image
) {
932 return mono_image_has_authenticode_entry (refass
->assembly
->image
);
938 /* System.Security.SecureString related internal calls */
940 static MonoImage
*system_security_assembly
= NULL
;
943 ves_icall_System_Security_SecureString_DecryptInternal (MonoArray
*data
, MonoObject
*scope
)
946 invoke_protected_memory_method (data
, scope
, FALSE
, &error
);
947 mono_error_set_pending_exception (&error
);
950 ves_icall_System_Security_SecureString_EncryptInternal (MonoArray
* data
, MonoObject
*scope
)
953 invoke_protected_memory_method (data
, scope
, TRUE
, &error
);
954 mono_error_set_pending_exception (&error
);
957 void invoke_protected_memory_method (MonoArray
*data
, MonoObject
*scope
, gboolean encrypt
, MonoError
*error
)
963 mono_error_init (error
);
965 if (system_security_assembly
== NULL
) {
966 system_security_assembly
= mono_image_loaded ("System.Security");
967 if (!system_security_assembly
) {
968 MonoAssembly
*sa
= mono_assembly_open ("System.Security.dll", NULL
);
970 g_assert_not_reached ();
971 system_security_assembly
= mono_assembly_get_image (sa
);
975 klass
= mono_class_load_from_name (system_security_assembly
,
976 "System.Security.Cryptography", "ProtectedMemory");
977 method
= mono_class_get_method_from_name (klass
, encrypt
? "Protect" : "Unprotect", 2);
979 params
[1] = scope
; /* MemoryProtectionScope.SameProcess */
981 mono_runtime_invoke_checked (method
, NULL
, params
, error
);