Thursday, April 17, 2014

SPTrustedRootAuthority -- Most important internal class for Claims Based Authentication

In wisdom unknown to me the SPTrustedRootAuthority (TRA) class and its manager SPTrustedRootAuthorityManager (TRA manager, both in Microsoft.SharePoint.Administration) are internal and sealed.  Big statement, probably nobody cares but me, so hear me out.  What if you wanted to add on to Central Administration so that CBA could be maitained 100% through the UI?  Can't do it with the classes on hand, because we can't link directly to those classes.

SharePoint maintains an internal Certificate Authority (CA) which just happens to be managed by the SPTrustedRootAuthorityManager.  Microsoft graciously provided us with a form in Central Admin and Power Shell commands to work with the list of certificates (see get-command -noun SPTrustedRootAuthority), but the only way to work one is through then PS command scripts.  This is OK, but it seems like SharePoint team took the easy way out and didn't finish the GUI in Central Admin.

So what's a boy (or girl for that matter) to do?  I went and found all of the PS Cmdlets that parallel the steps in the Claims Walkthrough, just so I wouldn't have to write a Forms app just to setup the SPTrustedLoginProvider.   That was great for me, but I'm a consultant these days and I need to get my clients up and running on this stuff.  If I can barely remember the sequence of command, how could they.  Especially when you want to add new Known Claim Values when a new set of secureables comes out.


Well I took it upon myself to create my own user interface to manage CBA trust providers and developed it into a set of 14 hive application pages, in the ADMIN folder (/_admin/TrustConfig, etc.) so that they would only be available through Central Admin and not through a normal site.   Configuring Trust is an administrative task after all...


So everybody knows when you setup a new CBA Trust you do the following:

  1. Get an X.509 certificate w/o the private key attached in a DER file.
  2. Load the certificate into SharePoint's Trusted Authority Manager (CA or PS usually works)
  3. Create new SPTrustedLoginProvider that references the certificate.
There's some subtleties though.  A X.509 certificate can be used for only one SPTrustedLoginProvider at a time.  Off hand I can't remember if it throws an error when you create the provider or if it error when you try and use it.  Either way, I remember the error message isn't very helpful!  The cert has to be loaded in SP's private CA ahead of time too.  So, why doesn't allow you to just reference the cert's Subject & Issuer?  May because it's important that you have all of the bits in the cert on hand? Maybe, its like the old days, when you couldn't deposit a picture of a check, you had to hand it over to the teller.

Anyway, that was only one problem, when you first setup the Login Provider.  You need to come back to one and update the Known Claim Values, maybe add a new Claim Type now and again too.  But try describing that over the phone (you may be better at than I am).

Solution, add those application pages to Central Admin.  But you'll need to use some reflection magic to get a hold of that data.  Now if you review my code I'm about to post, you may notice that there may have been more direct ways to get to the data, like accessing the TRA manager directly, or calling the "Certificate" property on the TRA.  I'm not saying my code is perfect, but it got me there.

What, you're about to see, is what the GOF would call Adapter Classes.  The first TrustedRootAuthority wraps the SPTrustedRootAuthority to provide access to the X509Certificate2 and the second, RootAuthority, wraps the SPCmdletGetTrustedRootAuthority Power Shell Cmdlet to get the set of all installed certificates.

These additions don't let you install new certificates, but that wouldn't be too hard once you've gotten this far.  They do allow you to get a hold of all of the installed certs so that you can pick and choose the certificate you want to add to your newly minted SPTrustedLoginProvider.



class TrustedRootAuthority
{
    static Type traType;
    static TrustedRootAuthority() {
       Assembly a = Assembly.Load("Microsoft.SharePoint, Version=14.0.0.0, " 
                              +"Culture=neutral, PublicKeyToken=71e9bce111e9429c");
       traType = a.GetType("Microsoft.SharePoint.Administration.SPTrustedRootAuthority",
                              true, true);
    }

    object tra;
    public TrustedRootAuthority(object tra) {
       this.tra = tra;
    }

    public X509Certificate2 Certificate {
       get {
           return traType.InvokeMember("m_Certificate", BindingFlags.NonPublic | 
                            BindingFlags.GetField | BindingFlags.Instance, null,
                            tra, null) as X509Certificate2;
       }
    }

}
      
class RootAuthority
{
    static ConstructorInfo ctor;
    static MethodInfo rdo;
    static RootAuthority() {
       Assembly a = Assembly.Load("Microsoft.SharePoint.PowerShell, Version=14.0.0.0, "+
                                  "Culture=neutral, PublicKeyToken=71e9bce111e9429c");
       Type t = a.GetType("Microsoft.SharePoint.PowerShell.SPCmdletGetTrustedRootAuthority",
                                  true, true);
       ctor = t.GetConstructor(new Type[0]);
       rdo =  t.GetMethod("RetrieveDataObjects", BindingFlags.NonPublic 
                                     | BindingFlags.Instance);
    }

    private object tra;

    public RootAuthority() {
        tra = ctor.Invoke(null);
    }

    public IEnumerable<TrustedRootAuthority> RetrieveDataObjects() {
        IEnumerable src = rdo.Invoke(tra, null) as IEnumerable;
        List<TrustedRootAuthority> ret = new List<TrustedRootAuthority>();
        foreach (object o in src) {
            ret.Add(new TrustedRootAuthority(o));
        }
        return ret;
    }
}




Tuesday, April 15, 2014

More on Quasigroup Block Ciphers

During the course of acquiring my Masters in Computer Science, I had the opportunity to do some crypto research.  It's probably landed me on a couple of watch lists, but what the heck, YOLO.  I still can fly to Nashville and just get tagged for my nephew's Play-Doh Christmas present in my carry-ons.

So, how to list research publications? Anti-chronologically? Randomly? No names just links?  On your curriculum vita it's newest to oldest, so AC it is.
Improved QGBC

PRNG Feedback Generator
Battey, "The Quasigroup Block Cipher and its Analysis," Graduate Thesis, University of Nebraska at Omaha, 2014.



Battey & Parakh, “Cryptanalysis of the Quasigroup Block Cipher,” Proceedings of  ACM SE’2014, Kennesaw, Georgia, USA,  2014.




QGBC Activity
Battey & Parakh, “A New Quasigroup Based Random Number Generator,” 2013 Internal Conference on Security & Management, pp. 235-241,  Las Vegas, Nevada, 2013.



Battey & Parakh, “An Efficient Quasigroup Block Cipher,” Wireless Personal Communications, Nov 2013, Vol. 73, Issue 1, pp 63-76.



Battey & Parakh, “Efficient Quasigroup Block Cipher for Sensor Networks,” 21st International Conference on Computer Communication and Networks (ICCCN), pp 1-5, Munich, Germany, 2012.

Monday, April 14, 2014

SharePoint Menu Item to Change your AD Password

It totally slays me why Microsoft hasn't included a feature to change your Active Directory password directly through SharePoint, especially when they position the system as an extranet portal.  Maybe it's because they want you to invest in UAG or something.

Anyway, adding such a feature is pretty straight forward.  You'll need to do the following high level steps:

1) Create a WebPart (Visual, SharePoint, or otherwise)
2) Create a page to host the web part
3) Add a CustomAction in an Elements file

So when I when through this process (1) was a Visual WebPart in Visual Studio 2010; (2) was part of a Files Module and deploys to the /StyleLibrary of the site; and (3) references a WebControl that is in the same namespace as my ChagePassword (1) VWP.

I'm going to assume that you know how to create a VWP and deploy it.  And, I'll assume you know how to create an ASPX page as part of a SharePoint project.  Also I'll assume, for now, you know all about the System.DirectoryServices.AccountManagement API, so that you can do all that work on your own.  In another post, I'll cover the Account Management API and cover some of the topics related to Kerberos and how that enhances the ability to work with the Active Directory API's in general.

Right now, we'll concentrate on how you'd deploy the ASPX page to the /StyleLibrary and how you deploy a custom action to the Standard Menu.  First off, I called my password change page ChagnePassword.ASPX and my new custom action ChangePasswordMenuItem, and I deployed my custom resources in a folder called AccountManagement.  Original, I know.

Ok, lets first start with the menu item WebControl.



public class ChangePasswordMenuItem : WebControl
{
       protected override void CreateChildControls() {
              base.CreateChildControls();

              MenuItemTemplate menuItem = new MenuItemTemplate() {
                     Text = "Change Password",
                     Description = "Change your Login Password",
                     Sequence = 1,
                     ClientOnClickNavigateUrl =  
                            SPContext.Current.Site.Url.ToString() +  
                            "/Style Library/AccountManagement/ChangePassword.aspx?Source=" + 
                            SPHttpUtility.UrlKeyValueEncode( 
                                          SPUtility.OriginalServerRelativeRequestUrl),
                     ImageUrl = SPContext.Current.Site.Url.ToString() + 
                            "/Style Library/AccountManagement/cp.png"
              };

              Controls.Add(menuItem);
       }
}

When this control is loaded, it creates a new menu item to be placed in the Standard Menu, otherwise know as the "User Menu," that one in the top right-hand corner.  The reason it's in this menu instead of another menu?  There's an addition you need to manually make to one of the Elements.xml files in your VS2010 SharePoint project.



<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
       <CustomAction
              Id="MyChangePassword"
              Location="Microsoft.SharePoint.StandardMenu"
              GroupId="PersonalActions"
              ControlAssembly="$SharePoint.Project.AssemblyFullName$"
              ControlClass="<NAMESPACE>.ChangePasswordMenuItem">
       </CustomAction>
</Elements>

The CustomAction tag in the elements file causes SharePoint to register a new menu item in the Standard Menu.  You can cut and past my code here, but you'll need to replace <NAMESPACE> with the namespace you're using in your project.

Next, you'll need to add a destination for the custom ASPX page you develop.  Remember I called mine ChangePassword.aspx?  We'll it's also in a project folders called SupportComponents\Style Library\AccountManagement, and I created a custom icon for my menu item that looks like a pair of keys on a key ring.  I actually modified a couple of other SharePoint icons to come up with this one.  It's pictured in the image at the top of this post.


<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <Module Name="SupportComponents" RootWebOnly="TRUE" Url="Style Library/AccountManagement">
      <File Path="SupportComponents\Style Library\AccountManagement\ChangePassword.aspx"
            Url="ChangePassword.aspx" />
      <File Path="SupportComponents\Style Library\AccountManagement\CP.png"  
            Url="CP.png" />
   </Module> 
</Elements>

This element file modification will copy both of my files to the ~/Style Library/AccountManagement folder.

So, once this project is deployed, we now have a custom action in the Standard Menu, that references a page in the Style Library, and that page hosts our web part that allows the user to change his Active Directory Password.