in xsec/enc/XSECCryptoUtils.cpp [75:251]
int SASLCleanXKMSPassPhrase(unsigned char * input, int inputLen, safeBuffer &output) {
// For now - this does *not* implement the full SASLPrep algorithm.
// THe NFKC form is not trivial to implement - so this is kept very simple.
// TODO - Fix this - it can be an interoperability issue as pass phrases from
// different implementations could be treated differently.
// Currently we only check for prohibited unput for chars < 0xFFFF and drop any
// chars over 0xFFFF
unsigned char * inp = new unsigned char[inputLen + 1];
ArrayJanitor<unsigned char> j_inp(inp);
memcpy(inp, input, inputLen);
inp[inputLen] = '\0';
XSECAutoPtrXMLCh uinput((char *) inp);
XMLSize_t l = XMLString::stringLen(uinput.get());
XMLCh* uoutput = new XMLCh[l + 1];
ArrayJanitor<XMLCh> j_uoutput(uoutput);
XMLSize_t i, j;
j = 0;
XMLCh ch1;
for (i = 0; i < l; ++i) {
ch1 = uinput.get()[i];
// Case one - char is < 0x10000
if (ch1 < 0xD800 || ch1 > 0xDFFF) {
// OK - ch1 is "real" value - let's see if it is legal
// The following switch tables are derived from
// RFC 3454 - see http://www.ietf.org/rfc/rfc3454.txt
// Non-ASCII Spaces - C.1.2
switch (ch1) {
case 0x00A0: // NO-BREAK SPACE
case 0x1680: // OGHAM SPACE MARK
case 0x2000: // EN QUAD
case 0x2001: // EM QUAD
case 0x2002: // EN SPACE
case 0x2003: // EM SPACE
case 0x2004: // THREE-PER-EM SPACE
case 0x2005: // FOUR-PER-EM SPACE
case 0x2006: // SIX-PER-EM SPACE
case 0x2007: // FIGURE SPACE
case 0x2008: // PUNCTUATION SPACE
case 0x2009: // THIN SPACE
case 0x200A: // HAIR SPACE
case 0x200B: // ZERO WIDTH SPACE
case 0x202F: // NARROW NO-BREAK SPACE
case 0x205F: // MEDIUM MATHEMATICAL SPACE
case 0x3000: // IDEOGRAPHIC SPACE
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - Non ASCII space character in XKMS pass phrase");
default:
break;
}
// ASCII Control characters
// Note - us unsigned, so always >= 0)
if ((ch1 <= 0x1F) || (ch1 == 0x7F)) {
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - ASCII control character in XKMS pass phrase");
}
// Non-ASCII Control Characters
if ((ch1 >= 0x80 && ch1 <= 0x9F) ||
(ch1 >= 0x206A && ch1 <= 0x206F) ||
(ch1 >= 0xFFF9 && ch1 <= 0xFFFC)) {
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - NON ASCII control character in XKMS pass phrase");
}
switch (ch1) {
case 0x06DD: // ARABIC END OF AYAH
case 0x070F: // SYRIAC ABBREVIATION MARK
case 0x180E: // MONGOLIAN VOWEL SEPARATOR
case 0x200C: // ZERO WIDTH NON-JOINER
case 0x200D: // ZERO WIDTH JOINER
case 0x2028: // LINE SEPARATOR
case 0x2029: // PARAGRAPH SEPARATOR
case 0x2060: // WORD JOINER
case 0x2061: // FUNCTION APPLICATION
case 0x2062: // INVISIBLE TIMES
case 0x2063: // INVISIBLE SEPARATOR
case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - NON ASCII control character in XKMS pass phrase");
default:
break; }
// 1D173-1D17A; [MUSICAL CONTROL CHARACTERS] is not relevant as we are looking at
// ch1 at the moment
// Private Use characters
if ((ch1 >= 0xE000 && ch1 <= 0xF8FF)) {
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - Private Use character in XKMS pass phrase");
}
// Non-character code points
if ((ch1 >= 0xFDD0 && ch1 <= 0xFDEF) ||
(ch1 >= 0xFFFE)) {
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - Non-character code points in XKMS pass phrase");
}
// Inappropriate for plain text characters
switch (ch1) {
case 0xFFF9: // INTERLINEAR ANNOTATION ANCHOR
case 0xFFFA: // INTERLINEAR ANNOTATION SEPARATOR
case 0xFFFB: // INTERLINEAR ANNOTATION TERMINATOR
case 0xFFFC: // OBJECT REPLACEMENT CHARACTER
case 0xFFFD: // REPLACEMENT CHARACTER
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - Innappropriate for plain text chararcters in XKMS pass phrase");
default:
break;
}
// Inappripriate for canonical representation characters
if (ch1 >= 0x2FF0 && ch1 <= 0x2FFB) {
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - Innappropriate for canonicalisation chararcters in XKMS pass phrase");
}
// Change display properties or are deprecated
switch (ch1) {
case 0x0340: // COMBINING GRAVE TONE MARK
case 0x0341: // COMBINING ACUTE TONE MARK
case 0x200E: // LEFT-TO-RIGHT MARK
case 0x200F: // RIGHT-TO-LEFT MARK
case 0x202A: // LEFT-TO-RIGHT EMBEDDING
case 0x202B: // RIGHT-TO-LEFT EMBEDDING
case 0x202C: // POP DIRECTIONAL FORMATTING
case 0x202D: // LEFT-TO-RIGHT OVERRIDE
case 0x202E: // RIGHT-TO-LEFT OVERRIDE
case 0x206A: // INHIBIT SYMMETRIC SWAPPING
case 0x206B: // ACTIVATE SYMMETRIC SWAPPING
case 0x206C: // INHIBIT ARABIC FORM SHAPING
case 0x206D: // ACTIVATE ARABIC FORM SHAPING
case 0x206E: // NATIONAL DIGIT SHAPES
case 0x206F: // NOMINAL DIGIT SHAPES
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - change display or deprecated chararcters in XKMS pass phrase");
default:
break;
}
// We got this far = just run with it for now
uoutput[j++] = ch1;
}
else {
throw XSECException(XSECException::XKMSError,
"SASLCleanXKMSPassPhrase - don't support XKMS pass phrase chars > 0xFFFF");
}
} /* for */
uoutput[j++] = chNull;
// Now transcode
char * utf8output= transcodeToUTF8(uoutput);
output.sbStrcpyIn(utf8output);
int ret = (int)strlen(utf8output);
XSEC_RELEASE_XMLCH(utf8output);
return ret;
}