/// <summary> /// Set Qop type /// </summary> /// <param name="dpspResponse">DpspResponse instance</param> /// <param name="digestValidationReq">DIGEST_VALIDATION_REQ structure</param> /// <returns>DIGEST_VALIDATION_REQ structure</returns> private static DIGEST_VALIDATION_REQ SetQopType( DpspResponse dpspResponse, DIGEST_VALIDATION_REQ digestValidationReq) { if (dpspResponse.MessageQop == null || dpspResponse.MessageQop.Length == 0) { digestValidationReq.QopType = QopType_Values.None; } else { switch (dpspResponse.MessageQop.ToLower()) { case QOP_AUTHENTICATION_NAME: digestValidationReq.QopType = QopType_Values.Authenticate; break; case QOP_AUTHENTICATION_AND_INTEGRITY_NAME: digestValidationReq.QopType = QopType_Values.AuthenticateAndIntegrity; break; case QOP_AUTHENTICATION_WITH_INTEGRITY_AND_ENCRYPTION_NAME: digestValidationReq.QopType = QopType_Values.AuthenticateWithIntegrityProtectionAndEncryption; break; default: throw new ArgumentException("invalid QopType value in digestResponse parameter"); } } return(digestValidationReq); }
/// <summary> /// Encode common part of DigestValidationRequest /// </summary> /// <param name="serverName">server name</param> /// <param name="domainName">domain name</param> /// <param name="accountName">account name</param> /// <param name="digestType">digest type</param> /// <param name="digestChallengeAlgorithm">digest challenge algorithm</param> /// <param name="dpspResponse">dpspResponse</param> /// <param name="payload">DIGEST_VALIDATION_REQ_Payload structure</param> /// <param name="digestValidationReq">digestValidationReq</param> private static void EncodeCommonPartOfDigestValidationRequest( string serverName, string domainName, string accountName, DigestType_Values digestType, string digestChallengeAlgorithm, DpspResponse dpspResponse, ref DIGEST_VALIDATION_REQ_Payload payload, ref DIGEST_VALIDATION_REQ digestValidationReq ) { digestValidationReq.MessageType = DIGEST_VALIDATION_REQ_MessageType_Values.Default; digestValidationReq.Version = DIGEST_VALIDATION_REQ_Version_Values.Default; digestValidationReq.DigestType = digestType; digestValidationReq = SetQopType(dpspResponse, digestValidationReq); digestValidationReq = SetAlgType(digestChallengeAlgorithm, digestValidationReq); digestValidationReq.CharsetType = CharsetType_Values.UTF8; digestValidationReq.NameFormat = NameFormat_Values.None; digestValidationReq.Flags = DIGEST_VALIDATION_FLAGS.FormatOfUserNameAndRealmIsDeterminedByDC | DIGEST_VALIDATION_FLAGS.RequestIsSentFromServer; digestValidationReq.Reserved3 = DIGEST_VALIDATION_REQ_Reserved3_Values.Default; digestValidationReq.Reserved4 = Reserved4_Values.Default; digestValidationReq.Pad1 = DIGEST_VALIDATION_REQ_Pad1_Values.Default; // Each of the strings MUST be included. If the string value is empty, // then a terminating null character MUST be used for the value. payload.Username = dpspResponse.GetAttributeValue(DpspUtility.USER_NAME_DIRECTIVE); payload.Realm = dpspResponse.GetAttributeValue(DpspUtility.REALM_DIRECTIVE); payload.Nonce = dpspResponse.GetAttributeValue(DpspUtility.NONCE_DIRECTIVE); payload.CNonce = dpspResponse.GetAttributeValue(DpspUtility.CNONCE_DIRECTIVE); payload.NonceCount = dpspResponse.GetAttributeValue(DpspUtility.NONCE_COUNT_DIRECTIVE); payload.QOP = dpspResponse.GetAttributeValue(DpspUtility.MESSAGE_QOP_DIRECTIVE); payload.Response = dpspResponse.GetAttributeValue(DpspUtility.RESPONSE_DIRECTIVE); payload.AccountName = accountName;; payload.ServerName = serverName; payload.Domain = domainName; }
/// <summary> /// This method constructs the digest request structure which is required to send from protocol client to protocol server. /// </summary> /// <param name="digestType">It indicates the DigestType field of the DIGEST_VALIDATION_REQ</param> /// <param name="algType">It indicates the AlgType field of the DIGEST_VALIDATION_REQ </param> /// <param name="ignoredFields">It indicates the fields that should be ignored by DC in DIGEST_VALIDATION_REQ </param> /// <param name="digestReq">The request structure for digest validation</param> private void GetDigestRequest( DigestType_Values digestType, AlgType_Values algType, IgnoredFields ignoredFields, out DIGEST_VALIDATION_REQ digestReq) { // create a temporary payload structure DIGEST_VALIDATION_REQ_Payload reqLoad = new DIGEST_VALIDATION_REQ_Payload(); reqLoad.AccountName = currentUserName; reqLoad.Algorithm = acceptedAlgType; reqLoad.Authzid = ""; reqLoad.Nonce = GenerateNonce(); reqLoad.CNonce = reqLoad.Nonce; reqLoad.Hentity = ""; reqLoad.NonceCount = nonceCountString; reqLoad.QOP = ""; reqLoad.Realm = sutDomainName; reqLoad.URI = "/"; reqLoad.Username = currentUserName; string servicename = serverName; string response = string.Empty; if (digestType == DigestType_Values.Basic) { reqLoad.Method = httpRequestMethodString; // calling RFC 2617 algorithms for calculating H(A1) and Response, when HTTP is involved. string strHA1 = DigestCalcHA1HTTP( reqLoad.Algorithm, reqLoad.Username, reqLoad.Realm, currentPassword, reqLoad.Nonce, reqLoad.CNonce, false); digestSessionKey = strHA1; response = DigestCalcResponseHTTP( strHA1, reqLoad.Nonce, reqLoad.NonceCount, reqLoad.CNonce, reqLoad.QOP, reqLoad.Method, reqLoad.URI, reqLoad.Hentity, false); } else if (digestType == DigestType_Values.SASL) { reqLoad.Method = saslRequestMethodString; // calling RFC 2617 algorithms for calculating H(A1) and Response, when SASL is involved. string strHA1 = DigestCalcHA1SASL( reqLoad.Authzid, reqLoad.Username, reqLoad.Realm, currentPassword, reqLoad.Nonce, reqLoad.CNonce, false); digestSessionKey = strHA1; response = DigestCalcResponseSASL( strHA1, reqLoad.Nonce, reqLoad.NonceCount, reqLoad.CNonce, reqLoad.QOP, reqLoad.URI, false, false); } string basicDigestCredentialString = "Digest username="******",realm=" + reqLoad.Realm + ",nonce=" + reqLoad.Nonce + ",uri=" + reqLoad.URI + ",cnonce=" + reqLoad.CNonce + ",nc=" + reqLoad.NonceCount + ",algorithm=" + reqLoad.Algorithm + ",response=" + response + ",qop=" + reqLoad.QOP + ",charset=" + encodingCodePageString + ",service-name=" + servicename; DpspResponse dpspResponse = DpspBasicResponse.Decode(basicDigestCredentialString); DIGEST_VALIDATION_REQ digestValidationReq = ApdsUtility.CreateDigestValidationRequestPacket( clientComputerName, string.Empty, string.Empty, reqLoad.Method, digestType, acceptedAlgType, dpspResponse); digestValidationReq.CharsetType = CharsetType_Values.ISO8859_1; digestValidationReq.AlgType = algType; digestValidationReq.Flags = (DIGEST_VALIDATION_FLAGS)5; digestValidationReq.Reserved3 = (DIGEST_VALIDATION_REQ_Reserved3_Values)ignoredFields.reserved3; digestValidationReq.Reserved4 = (Reserved4_Values)ignoredFields.reserved4; digestReq = digestValidationReq; }
/// <summary> /// Construct DIGEST_VALIDATION_REQ structure /// </summary> /// <param name="serverName">server name</param> /// <param name="domainName">domain name</param> /// <param name="accountName">account name</param> /// <param name="httpMethod">http method</param> /// <param name="digestType">digest type</param> /// <param name="digestChallengeAlgorithm">digest challenge algorithm</param> /// <param name="dpspResponse">dpspResponse class instance</param> /// <returns>DIGEST_VALIDATION_REQ structure</returns> /// <exception cref="ArgumentNullException"> /// Thrown when dpspResponse or httpMethod is null /// </exception> /// <exception cref="ArgumentException"> /// Thrown when httpMethod or digestType input is invalid /// </exception> public static DIGEST_VALIDATION_REQ CreateDigestValidationRequestPacket( string serverName, string domainName, string accountName, string httpMethod, DigestType_Values digestType, string digestChallengeAlgorithm, DpspResponse dpspResponse) { if (dpspResponse == null) { throw new ArgumentNullException("dpspResponse"); } if (httpMethod == null) { throw new ArgumentNullException("httpMethod"); } DIGEST_VALIDATION_REQ_Payload payload = new DIGEST_VALIDATION_REQ_Payload(); DIGEST_VALIDATION_REQ digestValidationReq = new DIGEST_VALIDATION_REQ(); if (digestType == DigestType_Values.Basic) { EncodeCommonPartOfDigestValidationRequest( serverName, domainName, accountName, digestType, digestChallengeAlgorithm, dpspResponse, ref payload, ref digestValidationReq); payload.Algorithm = dpspResponse.GetAttributeValue(DpspUtility.ALGORITHM_DIRECTIVE); payload.URI = dpspResponse.GetAttributeValue(DpspUtility.BASIC_DIGEST_URI_DIRECTIVE); if (httpMethod.ToUpper().Equals(HTTP_GET) || httpMethod.ToLower().Equals(HTTP_PUT)) { payload.Method = httpMethod; } else { throw new ArgumentException("invalid http method", "httpMethod"); } } else if (digestType == DigestType_Values.SASL) { EncodeCommonPartOfDigestValidationRequest( serverName, domainName, accountName, digestType, digestChallengeAlgorithm, dpspResponse, ref payload, ref digestValidationReq); payload.Method = SASL_AUTHENTICATE; payload.URI = dpspResponse.GetAttributeValue(DpspUtility.SASL_DIGEST_URI_DIRECTIVE); payload.Authzid = dpspResponse.GetAttributeValue(DpspUtility.AUTHZID_DIRECTIVE); payload.Hentity = dpspResponse.GetAttributeValue(DpspUtility.HENTITY_DIRECTIVE); } else { throw new ArgumentException( "invalid digestType value", "digestType"); } digestValidationReq.Payload = payload.GetBytes(); digestValidationReq = UpdatePacketInfo(digestValidationReq); return(digestValidationReq); }