Skip to content

Commit

Permalink
Use Enumeration for OTPHashAlgorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
ejisan committed Jul 24, 2016
1 parent 35dcb62 commit 1b7bbd0
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 30 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/ejisan/scalauth/otp/GoogleAuthenticator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ object GoogleAuthenticator {
* @param algorithm the name of selected hashing algorithm
* @param digits the length of returning OTP pin code string
*/
def hotp(algorithm: OTPHashAlgorithm = OTPHashAlgorithm.SHA1, digits: Int = 6): HOTP = {
def hotp(algorithm: OTPHashAlgorithm.Value = OTPHashAlgorithm.SHA1, digits: Int = 6): HOTP = {
require(digits >= 6, s"`digits` must be greater than or equal to 6, but it is '$digits'.")
HOTP(algorithm, digits)
}
Expand All @@ -37,7 +37,7 @@ object GoogleAuthenticator {
* @param digits the length of returning OTP pin code string
* @param period the period of seconds
*/
def totp(algorithm: OTPHashAlgorithm = OTPHashAlgorithm.SHA1, digits: Int = 6, period: Int = 30): TOTP = {
def totp(algorithm: OTPHashAlgorithm.Value = OTPHashAlgorithm.SHA1, digits: Int = 6, period: Int = 30): TOTP = {
require(digits >= 6, s"`digits` must be greater than or equal to 6, but it is '$digits'.")
require(period >= 5, s"`period` must be greater than or equal to 5, but it is '$period'.")
TOTP(algorithm, digits, period)
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/ejisan/scalauth/otp/HOTP.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package ejisan.scalauth.otp
* @param algorithm the name of selected hashing algorithm
* @param digits the length of returning OTP pin code string
*/
class HOTP private (val algorithm: OTPHashAlgorithm, val digits: Int) {
class HOTP private (val algorithm: OTPHashAlgorithm.Value, val digits: Int) {
/** Generates OTP pin code with a given user's secret and a counter.
*
* @param secret the user's secret
Expand Down Expand Up @@ -78,7 +78,7 @@ object HOTP {
*
* @return pin code digits
*/
def apply(algorithm: OTPHashAlgorithm, digits: Int, secret: OTPSecretKey, counter: Long): String = {
def apply(algorithm: OTPHashAlgorithm.Value, digits: Int, secret: OTPSecretKey, counter: Long): String = {
val msg = BigInt(counter).toByteArray.reverse.padTo(8, 0.toByte).reverse
val hash = OTPHasher(algorithm, secret, msg)
val offset = hash(hash.length - 1) & 0xf
Expand All @@ -95,7 +95,7 @@ object HOTP {
* @param algorithm the name of selected hashing algorithm
* @param digits the length of returning OTP pin code string
*/
def apply(algorithm: OTPHashAlgorithm, digits: Int): HOTP = {
def apply(algorithm: OTPHashAlgorithm.Value, digits: Int): HOTP = {
// Requirements
require(digits > 0, s"digits must be greater than 0, but it is ($digits)")
new HOTP(algorithm, digits)
Expand Down
16 changes: 4 additions & 12 deletions src/main/scala/ejisan/scalauth/otp/OTPHashAlgorithm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,11 @@ package ejisan.scalauth.otp
import javax.crypto.spec.SecretKeySpec
import javax.crypto.Mac

/** A hashing algorithm for OTP.
*
* @param value the algorithm's name
*/
class OTPHashAlgorithm private (val value: String) extends AnyVal {
override def toString: String = s"OTPHashAlgorithm($value)"
}

/** Default algorithms. */
object OTPHashAlgorithm {
val SHA1: OTPHashAlgorithm = new OTPHashAlgorithm("HmacSha1")
val SHA256: OTPHashAlgorithm = new OTPHashAlgorithm("HmacSha256")
val SHA512: OTPHashAlgorithm = new OTPHashAlgorithm("HmacSha512")
object OTPHashAlgorithm extends Enumeration {
val SHA1 = Value("HmacSha1")
val SHA256 = Value("HmacSha256")
val SHA512 = Value("HmacSha512")
}

class UnsupportedOTPHashAlgorithmException(message: String) extends Exception(message: String)
4 changes: 2 additions & 2 deletions src/main/scala/ejisan/scalauth/otp/OTPHasher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ private[otp] object OTPHasher {
* @param secret the secret for the hashing
* @param message the message that will be hashed
*/
def apply(algorithm: OTPHashAlgorithm, secret: OTPSecretKey, message: Array[Byte]): Array[Byte] = {
val hmac: Mac = Mac.getInstance(algorithm.value)
def apply(algorithm: OTPHashAlgorithm.Value, secret: OTPSecretKey, message: Array[Byte]): Array[Byte] = {
val hmac: Mac = Mac.getInstance(algorithm.toString)
hmac.init(new SecretKeySpec(byteArray(secret), "RAW"))
hmac.doFinal(message)
}
Expand Down
12 changes: 3 additions & 9 deletions src/main/scala/ejisan/scalauth/otp/OTPUriEncoder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@ import java.net.URI

/** OTP URI encoder */
object OTPUriEncoder {
/** Supported algorithms */
private val algorithms: Set[(OTPHashAlgorithm, String)] = Set(
OTPHashAlgorithm.SHA1 -> "SHA1",
OTPHashAlgorithm.SHA256 -> "SHA256",
OTPHashAlgorithm.SHA512 -> "SHA512")

private def formalizeHashAlgorithm(algorithm: OTPHashAlgorithm): String
= algorithms.find(_._1 == algorithm).map(_._2).getOrElse(throw new UnsupportedOTPHashAlgorithmException(algorithm.toString))
private def formalizeHashAlgorithm(algorithm: OTPHashAlgorithm.Value): String
= OTPHashAlgorithm.values.find(_.toString == algorithm).map(_.toString).getOrElse(throw new UnsupportedOTPHashAlgorithmException(algorithm.toString))

private def buildQuery(
secret: OTPSecretKey,
algorithm: OTPHashAlgorithm,
algorithm: OTPHashAlgorithm.Value,
digits: Int,
issuer: String,
additional: (String, Any)*): String
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/ejisan/scalauth/otp/TOTP.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package ejisan.scalauth.otp
* @param digits the length of returning OTP pin code string
* @param period the period of seconds
*/
class TOTP private (val algorithm: OTPHashAlgorithm, val digits: Int, val period: Int) {
class TOTP private (val algorithm: OTPHashAlgorithm.Value, val digits: Int, val period: Int) {
/** Generates OTP pin code with a given user's secret.
*
* @param secret the user's secret
Expand Down Expand Up @@ -69,7 +69,7 @@ object TOTP {
* @param digits the length of returning OTP pin code string
* @param period the period of seconds
*/
def apply(algorithm: OTPHashAlgorithm, digits: Int, period: Int): TOTP = {
def apply(algorithm: OTPHashAlgorithm.Value, digits: Int, period: Int): TOTP = {
// Requirements
require(digits > 0, s"digits must be greater than 0, but it is ($digits)")
require(period > 0, s"period must be greater than 0, but it is ($period)")
Expand Down

0 comments on commit 1b7bbd0

Please sign in to comment.