Sky Software Homepage LogicNP Software Knowledge Base And FAQ

 
Contact Product Support    SearchSearch      Subscribe to the RSS feed for this forum

CODE: Sample CryptoLicense.IsMachineCodeValid implementation

 
Subscribe to the RSS feed for this forum  Forum Index -> CryptoLicensing For .Net
View previous topic :: View next topic  
Author Message
Support



Joined: 18 Jul 2005
Posts: 731

Posted: Tue Aug 18, 2009 5:05 am    Post subject: CODE: Sample CryptoLicense.IsMachineCodeValid implementation

When a machine-locked is being validated, it byte-compares the machine code embedded in the license with the code returned by the GetLocalMachineCode method. To have more control over this, override the CryptoLicense.IsMachineCodeValid method. This can be useful when you want to implement a somewhat lenient machine code comparison method instead of the default strict byte-comparison. For example, your machine code could consist of a combination of the CPU-ID, BIOS serial number, amount of memory, hard-disk serial number and the MAC address. You may want to allow one or more components of the machine code to change so that every small hardware change does not make the license invalid. The following code demonstrates this:

[C#]
Code:

public class CustomCryptoLicense : CryptoLicense
{
  // Override to provide custom machine code
  // This example uses a combo of the CPU-ID and motherboard serial as the machine code
  // The machine is considered matched if either of the two match
  public override byte[] GetLocalMachineCode()
  {
      byte[] ret = null;
      try
      {
          ret = CombineBuffersWithLength(GetCPUId(), GetMBSerial());
      }
      catch { }

      // Fall back to base implementation if failed
      if(ret==null || ret.Length==2)
          ret = base.GetLocalMachineCode();

      return ret;
  }

  public override bool IsMachineCodeValid()
  {
      try
      {
          byte[] embeddedMachineCode = this.MachineCode;
          byte[] localMachineCode = this.GetLocalMachineCode();

          byte[] cpuid1, cpuid2, mbserial1, mbserial2;

          if (SplitBuffer(embeddedMachineCode, out cpuid1, out mbserial1) && SplitBuffer(localMachineCode, out cpuid2, out mbserial2))
          {
              // Consider valid of either cpu-id or mb-serial matches
              if (AreBuffersEqual(cpuid1, cpuid2) || AreBuffersEqual(mbserial1, mbserial2))
                  return true;
              else
                  return false;
          }
      }
      catch { }

      // Fall back to base implementation if failed
      return base.IsMachineCodeValid();

  }

  // Gets the CPU-ID of the local machine
  static internal byte[] GetCPUId()
  {
      try
      {
          ManagementClass mgmt = new ManagementClass("Win32_Processor");
          ManagementObjectCollection objCol = mgmt.GetInstances();
          foreach (ManagementObject obj in objCol)
          {
              // Only use CPU-ID from the first CPU
              string cpuInfo = obj.Properties["ProcessorId"].Value.ToString();
              if (cpuInfo != null && cpuInfo.Length > 0)
              {
                  byte[] ret = Encoding.UTF8.GetBytes(cpuInfo);
                  return ret;
              }
          }
      }
      catch { }

      return new byte[0];
  }

  static internal byte[] GetMBSerial()
  {
      try
      {
          ManagementClass mgmt = new ManagementClass("Win32_BaseBoard");
          ManagementObjectCollection objCol = mgmt.GetInstances();
          foreach (ManagementObject obj in objCol)
          {
              // Only use CPU-ID from the first CPU
              string mbserial = obj.Properties["SerialNumber"].Value.ToString();
              if (mbserial != null && mbserial.Length > 0)
              {
                  byte[] ret = Encoding.UTF8.GetBytes(mbserial);
                  return ret;
              }
          }
      }
      catch { }
      return new byte[0];
  }

  static byte[] CombineBuffersWithLength(byte[] buff1, byte[] buff2)
  {
      // Returned format is:
      // buff1length-....buff1....-buff2length-...buff2....
      byte[] ret = new byte[buff1.Length + buff2.Length + 2];
      ret[0] = (byte)buff1.Length;
      buff1.CopyTo(ret, 1);
      ret[buff1.Length + 1] = (byte)buff2.Length;
      buff2.CopyTo(ret, buff1.Length + 2);

      return ret;
  }

  static bool AreBuffersEqual(byte[] buff1,byte[] buff2)
  {
      try
      {
          if (buff1.Length != buff2.Length)
              return false;
          for (int i = 0; i < buff1.Length; i++)
          {
              if (buff1[i] != buff2[i])
                  return false;
          }
          return true;
      }
      catch { }

      return false;
  }

  // Gets machine code components
  static bool SplitBuffer(byte[] buff, out byte[] buff1, out byte[] buff2)
  {
      buff1 = buff2 = null;

      try
      {
          byte buff1Length = buff[0];
          buff1 = new byte[buff1Length];
          Buffer.BlockCopy(buff, 1, buff1, 0, buff1Length);

          byte buff2Length = buff[buff1Length + 1];
          buff2 = new byte[buff2Length];
          Buffer.BlockCopy(buff, buff1Length + 2, buff2, 0, buff2Length);

          return true;
      }
      catch
      {
            buff1 = buff2 = null;
      }

      return false;
  }
}

// Validating a license...

CustomCryptoLicense lic = new CustomCryptoLicense();

lic.ValidationKey = "<<validation key for your project>>";
lic.LicenseCode = "<<License code with custom machine code embedded>>";

// Validate license
MessageBox.Show(lic.Status.ToString());



[VB.Net]
Code:
Public Class CustomCryptoLicense
  Inherits CryptoLicense
  ' Override to provide custom machine code
  ' This example uses a combo of the CPU-ID and motherboard serial as the machine code
  ' The machine is considered matched if either of the two match
  Public Overrides Function GetLocalMachineCode() As Byte()
      Dim ret As Byte() = Nothing

      Try
          ret = CombineBuffersWithLength(GetCPUId(), GetMBSerial())
      Catch ex As Exception

      End Try

      ' Fall back to base implementation if failed
      If ret Is Nothing = True Or ret.Length = 2 Then
          ret = MyBase.GetLocalMachineCode()
      End If

      Return ret   
  End Function

  Public Overrides Function IsMachineCodeValid() As Boolean
      Try
          Dim embeddedMachineCode As Byte() = Me.MachineCode
          Dim localMachineCode As Byte() = Me.GetLocalMachineCode()

          Dim cpuid1, cpuid2, mbserial1, mbserial2 As Byte()
          cpuid1 = Nothing
          cpuid2 = Nothing
          mbserial1 = Nothing
          mbserial2 = Nothing

          If (SplitBuffer(embeddedMachineCode, cpuid1, mbserial1) And SplitBuffer(localMachineCode, cpuid2, mbserial2)) Then
              ' Consider valid of either cpu-id or mb-serial matches
              If (AreBuffersEqual(cpuid1, cpuid2) Or AreBuffersEqual(mbserial1, mbserial2)) Then
                  Return True
              Else
                  Return False
              End If
          End If
     Catch ex As Exception

      End Try

      ' Fall back to base implementation if failed
      Return MyBase.IsMachineCodeValid()
  End Function

  ' Gets the CPU-ID of the local machine
  Protected Shared Function GetCPUId() As Byte()
      Dim mgmt As ManagementClass = New ManagementClass("Win32_Processor")
      Dim objCol As ManagementObjectCollection = mgmt.GetInstances()
      Dim obj As ManagementObject

      For Each obj In objCol
          ' Only use CPU-ID from the first CPU
          Dim cpuInfo As String = obj.Properties("ProcessorId").Value.ToString()
          If (cpuInfo Is Nothing = False And cpuInfo.Length > 0) Then
              Dim ret As Byte() = Encoding.UTF8.GetBytes(cpuInfo)
              Return ret
          End If
      Next

      Return New Byte(0) {}
  End Function


  Protected Shared Function GetMBSerial() As Byte()
      Try
          Dim mgmt As ManagementClass = New ManagementClass("Win32_BaseBoard")
          Dim objCol As ManagementObjectCollection = mgmt.GetInstances()
          Dim obj As ManagementObject

          For Each obj In objCol
              ' Only use CPU-ID from the first CPU
              Dim mbserial As String = obj.Properties("SerialNumber").Value.ToString()
              If (mbserial Is Nothing = False And mbserial.Length > 0) Then
                  Dim ret As Byte() = Encoding.UTF8.GetBytes(mbserial)
                  Return ret
              End If
          Next
      Catch ex As Exception

      End Try
      Return New Byte(0) {}     
  End Function
 
  Shared Function CombineBuffersWithLength(ByVal buff1 As Byte(), ByVal buff2 As Byte()) As Byte()
      ' Returned format is:
      ' buff1length-....buff1....-buff2length-...buff2....
      Dim ret As Byte() = New Byte(buff1.Length + buff2.Length + 2) {}
      ret(0) = CType(buff1.Length, Byte)
      buff1.CopyTo(ret, 1)
      ret(buff1.Length + 1) = CType(buff2.Length, Byte)
      buff2.CopyTo(ret, buff1.Length + 2)

      Return ret     
  End Function

  Shared Function AreBuffersEqual(ByVal buff1 As Byte(), ByVal buff2 As Byte()) As Boolean
      Try
          If (buff1.Length <> buff2.Length) Then
              Return False
          End If
          Dim i As Integer
          For i = 0 To buff1.Length - 1
              If (buff1(i) <> buff2(i)) Then
                  Return False
              End If
          Next i

          Return True

      Catch ex As Exception
      End Try

      Return False     
  End Function
 
  ' Gets machine code components
  Shared Function SplitBuffer(ByVal buff As Byte(), ByRef buff1 As Byte(), ByRef buff2 As Byte()) As Boolean
      buff1 = Nothing
      buff2 = Nothing

      Try
          Dim buff1Length As Byte = buff(0)
          buff1 = New Byte(buff1Length) {}
          Buffer.BlockCopy(buff, 1, buff1, 0, buff1Length)

          Dim buff2Length As Byte = buff(buff1Length + 1)
          buff2 = New Byte(buff2Length) {}
          Buffer.BlockCopy(buff, buff1Length + 2, buff2, 0, buff2Length)

          Return True
      Catch
          buff1 = Nothing
          buff2 = Nothing

      End Try

      Return False
  End Function
 
End Class   

   
' Validating a license...

Dim lic As CustomCryptoLicense = New CustomCryptoLicense()

lic.ValidationKey = "<<validation key for your project>>"
lic.LicenseCode = "<<License code with custom machine code embedded>>"

' Validate license
MessageBox.Show(lic.Status.ToString())
Back to top
Display posts from previous:   
Forum Index -> CryptoLicensing For .Net All times are GMT
Page 1 of 1

 
Jump to:  


Powered by phpBB © 2001, 2005 phpBB Group