Last active
August 29, 2015 13:57
-
-
Save lennybacon/9661030 to your computer and use it in GitHub Desktop.
Sanitizing Strings according to Windows Client Certificate Enrollment Protocol [MS-WCCE]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static partial class StringExtensions | |
{ | |
/// <summary> | |
/// Sanitizes the string according to Windows Client Certificate Enrollment | |
/// Protocol: http://msdn.microsoft.com/en-us/library/cc249879.aspx | |
/// </summary> | |
/// <param name="input">The input.</param> | |
/// <returns>System.String.</returns> | |
/// <remarks> | |
/// All disallowed characters in the original name MUST be replaced with | |
/// the appropriate replacements values as specified in section | |
/// 3.1.1.4.1.1.2: http://msdn.microsoft.com/en-us/library/cc249743.aspx. | |
/// The sanitized name MUST be truncated to no more than 51 characters in | |
/// total length. The truncated name MUST NOT exceed 51 characters. If an | |
/// incomplete sanitized character sequence remains at the end of the | |
/// string (for example, !002 instead of !0023), the incomplete sequence | |
/// MUST be truncated completely. | |
/// The characters that were removed or truncated from the sanitized string | |
/// in the preceding bulleted item MUST be hashed according to the rules | |
/// specified in section 3.1.1.4.1.1.1. The resultant hash MUST be | |
/// converted to a 5-character string. The string MUST be five characters | |
/// in total length and MUST be padded with leading zeros on the left to | |
/// ensure a total length of five characters. | |
/// A minus sign (–) MUST be appended to the truncated sanitized name | |
/// followed by the 5-character string that contains the hash value. | |
/// </remarks> | |
public static string ToWcceSanitizedString(this string input) | |
{ | |
var sanitizedString = string.Empty; | |
var hashString = string.Empty; | |
var exclusions = | |
new List<char> | |
{ | |
'!', | |
'"', | |
'#', | |
'%', | |
'&', | |
'\'', | |
'(', | |
')', | |
'*', | |
'+', | |
',', | |
'/', | |
':', | |
';', | |
'<', | |
'=', | |
'>', | |
'?', | |
'[', | |
'\\', | |
']', | |
'^', | |
'`', | |
'{', | |
'|', | |
'}', | |
}; | |
foreach (var c in input) | |
{ | |
var charCode = (int)c; | |
if (charCode >= 0x20 && | |
charCode <= 0x7F && | |
exclusions.IndexOf(c) == -1) | |
{ | |
if (sanitizedString.Length + 1 > 51) | |
{ | |
hashString = hashString + c; | |
continue; | |
} | |
sanitizedString = sanitizedString + c; | |
continue; | |
} | |
if (sanitizedString.Length + 5 > 51) | |
{ | |
hashString = hashString + "!00" + charCode.ToString("X2"); | |
continue; | |
} | |
sanitizedString = sanitizedString + "!00" + charCode.ToString("X2"); | |
} | |
if (!string.IsNullOrWhiteSpace(hashString)) | |
{ | |
UInt16 hashSeed = 0; | |
const ushort value = 0x8000; | |
foreach (var c in hashString) | |
{ | |
var lowBit = (UInt16)(((value & hashSeed) != 0) ? 1 : 0); | |
hashSeed = (UInt16)(((hashSeed << 1) | lowBit) + c); | |
} | |
sanitizedString += | |
"-" + | |
hashSeed.ToString(CultureInfo.InvariantCulture).PadLeft(5, '0'); | |
} | |
return sanitizedString.ToLowerInvariant(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment