11/*******************************************************************************
2- * Copyright (c) 2008, 2009 IBM Corporation and others.
2+ * Copyright (c) 2008, 2025 IBM Corporation and others.
33 * All rights reserved. This program and the accompanying materials
44 * are made available under the terms of the Eclipse Public License 2.0
55 * which accompanies this distribution, and is available at
1616
1717import com .ibm .sip .util .log .Log ;
1818import com .ibm .sip .util .log .LogMgr ;
19+ import com .ibm .ws .common .crypto .CryptoUtils ;
1920
2021/**
2122 * Digest-generation utilities for the digest code. This class contains code
@@ -68,7 +69,7 @@ private static String toHexString(byte b[]) {
6869 }
6970
7071 /**
71- * Caculate the MD5 digest of the given byte array.
72+ * Caculate the MD5 or SHA256 digest (based on whether fips is enabled) of the given byte array.
7273 * @param msg The message to hash
7374 * @param digester The digester object to use.
7475 * @return A hashed representation of the message.
@@ -119,14 +120,15 @@ private static String textDigest(byte[] textBytes, MessageDigest digester)
119120
120121 /**
121122 * Calculate the A1 (username-realm-password) value for the digest.
122- * This is the 'plain md5' version, as opposed to the 'md5-sess' value,
123- * calculated by the method createA1MD5Sess.
123+ * This is the 'plain md5'/'sha256' version, as opposed to the 'md5-sess'/'sha256-sess' value (based on whether fips is enabled) ,
124+ * calculated by the method createA1MD5Sess/createA1SHA256Sess .
124125 *
125126 * @param user The username
126127 * @param realm The authentication realm.
127128 * @param passwd The user password.
128129 * @return A1 value as a string.
129130 * @see #createA1MD5Sess(String, String, String, String, String,
131+ * MessageDigest)/#createA1SHA256Sess(String, String, String, String, String,
130132 * MessageDigest)
131133 */
132134 public static String createHashedA1 (String user , String realm ,
@@ -187,6 +189,40 @@ private static String createA1MD5Sess(String ha1, String nonce,
187189 }
188190 return hexHash ;
189191 }
192+
193+ /**
194+ * Calculate the A1 (username-realm-password) value for the digest.
195+ * This is the 'SHA256-sess' version, which hashes the value username and
196+ * password along with the server and client nonces
197+ *
198+ * @param ha1 The non-sha256-sess value for a1 (hashed once)
199+ * @param nonce The server-side nonce.
200+ * @param cnonce The client-side nonce.
201+ * @param digester The digester to use for hashing.
202+ *
203+ * @return A1 value as a string.
204+ * @see #createA1(String, String, String)
205+ */
206+ private static String createA1SHA256Sess (String ha1 , String nonce ,
207+ String cnonce , MessageDigest digester )
208+ {
209+ if (c_logger .isTraceEntryExitEnabled ()) {
210+ c_logger .traceEntry (null , "createA1SHA256Sess" ,
211+ new Object [] {ha1 , nonce , cnonce , digester });
212+ }
213+ StringBuffer buff = new StringBuffer (BUFFER_INITIAL_SIZE );
214+ buff .append (ha1 );
215+ buff .append (":" );
216+ buff .append (nonce );
217+ buff .append (":" );
218+ buff .append (cnonce );
219+ String hexHash = buff .toString ();
220+
221+ if (c_logger .isTraceEntryExitEnabled ()) {
222+ c_logger .traceExit (null , "createA1SHA256Sess" , hexHash );
223+ }
224+ return hexHash ;
225+ }
190226
191227 /**
192228 * Create an A2 value for use with the auth-int QOP value. I.e. one that
@@ -307,7 +343,7 @@ private static String createKD(String HA1, String nonce, String nc,
307343 * @param cnonce The client-side nonce
308344 * @param uri The request URI
309345 * @param algorithm The algorithm to use. Could be either 'MD5' or
310- * 'MD5-sess'
346+ * 'MD5-sess' / 'SHA256' or 'SHA256-sess'
311347 * @param sipMethod The sip method of the client request.
312348 * @param body The message body to authenticate. Only needed if
313349 * qop="auth-int"
@@ -355,7 +391,7 @@ public static String createDigestFromAuthParams(String username,
355391 * @param cnonce The client-side nonce
356392 * @param uri The request URI
357393 * @param algorithm The algorithm to use. Could be either 'MD5' or
358- * 'MD5-sess'
394+ * 'MD5-sess'/ 'SHA256' or 'SHA256-sess'
359395 * @param sipMethod The sip method of the client request.
360396 * @param body The message body to authenticate. Only needed if
361397 * qop="auth-int"
@@ -371,11 +407,14 @@ public static String createDigestFromAuthParams(String ha1, String nonce,
371407 cnonce , uri , algorithm , sipMethod , body });
372408 }
373409 MessageDigest digester = ThreadLocalStorage .getMessageDigest ();
374- if (algorithm != null && algorithm .equals (DigestConstants .ALG_MD5_SESS )) {
375- String A1 = createA1MD5Sess (ha1 , nonce , cnonce , digester );
376- ha1 = textDigest (A1 , digester );
410+ String A1 = createA1MD5Sess (ha1 , nonce , cnonce , digester );
411+
412+ //if fips is enabled
413+ if (CryptoUtils .isFips140_3EnabledWithBetaGuard () && algorithm != null && algorithm .equals (DigestConstants .ALG_SHA256_SESS )) {
414+ A1 = createA1SHA256Sess (ha1 , nonce , cnonce , digester );
377415 }
378416
417+ ha1 = textDigest (A1 , digester );
379418 String A2 = null ;
380419 if (sipMethod == null )
381420 sipMethod = DigestConstants .METHOD_DEFAULT ;
0 commit comments