Skip to content

Commit

Permalink
KEYCLOAK-11745 Multi-factor authentication (keycloak#6459)
Browse files Browse the repository at this point in the history
Co-authored-by: Christophe Frattino <christophe.frattino@elca.ch>
Co-authored-by: Francis PEROT <francis.perot@elca.ch>
Co-authored-by: rpo <harture414@gmail.com>
Co-authored-by: mposolda <mposolda@gmail.com>
Co-authored-by: Jan Lieskovsky <jlieskov@redhat.com>
Co-authored-by: Denis <drichtar@redhat.com>
Co-authored-by: Tomas Kyjovsky <tkyjovsk@redhat.com>
  • Loading branch information
8 people committed Nov 14, 2019
1 parent e7e49c1 commit 4553234
Show file tree
Hide file tree
Showing 292 changed files with 9,444 additions and 4,093 deletions.
38 changes: 29 additions & 9 deletions common/src/main/java/org/keycloak/common/util/Base64Url.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,38 @@
public class Base64Url {
public static String encode(byte[] bytes) {
String s = Base64.encodeBytes(bytes);
s = s.split("=")[0]; // Remove any trailing '='s
return encodeBase64ToBase64Url(s);
}

public static byte[] decode(String s) {
s = encodeBase64UrlToBase64(s);
try {
// KEYCLOAK-2479 : Avoid to try gzip decoding as for some objects, it may display exception to STDERR. And we know that object wasn't encoded as GZIP
return Base64.decode(s, Base64.DONT_GUNZIP);
} catch (Exception e) {
throw new RuntimeException(e);
}
}


/**
* @param base64 String in base64 encoding
* @return String in base64Url encoding
*/
public static String encodeBase64ToBase64Url(String base64) {
String s = base64.split("=")[0]; // Remove any trailing '='s
s = s.replace('+', '-'); // 62nd char of encoding
s = s.replace('/', '_'); // 63rd char of encoding
return s;
}

public static byte[] decode(String s) {
s = s.replace('-', '+'); // 62nd char of encoding

/**
* @param base64Url String in base64Url encoding
* @return String in base64 encoding
*/
public static String encodeBase64UrlToBase64(String base64Url) {
String s = base64Url.replace('-', '+'); // 62nd char of encoding
s = s.replace('_', '/'); // 63rd char of encoding
switch (s.length() % 4) // Pad with trailing '='s
{
Expand All @@ -48,12 +72,8 @@ public static byte[] decode(String s) {
throw new RuntimeException(
"Illegal base64url string!");
}
try {
// KEYCLOAK-2479 : Avoid to try gzip decoding as for some objects, it may display exception to STDERR. And we know that object wasn't encoded as GZIP
return Base64.decode(s, Base64.DONT_GUNZIP);
} catch (Exception e) {
throw new RuntimeException(e);
}

return s;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,150 +28,164 @@ public class CredentialRepresentation {
public static final String PASSWORD = "password";
public static final String TOTP = "totp";
public static final String HOTP = "hotp";
public static final String CLIENT_CERT = "cert";
public static final String KERBEROS = "kerberos";

protected String type;
protected String device;
private String id;
private String type;
private String userLabel;
private Long createdDate;
private String secretData;
private String credentialData;
private Integer priority;

private String value;

// Plain-text value of credential (used for example during import from manually created JSON file)
protected String value;
// only used when updating a credential. Might set required action
protected Boolean temporary;

// Value stored in DB (used for example during export/import)
// All those fields are just for backwards compatibility
@Deprecated
protected String device;
@Deprecated
protected String hashedSaltedValue;
@Deprecated
protected String salt;
@Deprecated
protected Integer hashIterations;
@Deprecated
protected Integer counter;
@Deprecated
private String algorithm;
@Deprecated
private Integer digits;
@Deprecated
private Integer period;
private Long createdDate;
@Deprecated
private MultivaluedHashMap<String, String> config;

// only used when updating a credential. Might set required action
protected Boolean temporary;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getValue() {
return value;
public String getUserLabel() {
return userLabel;
}

public void setValue(String value) {
this.value = value;
public void setUserLabel(String userLabel) {
this.userLabel = userLabel;
}

public String getDevice() {
return device;
public String getSecretData() {
return secretData;
}

public void setDevice(String device) {
this.device = device;
public void setSecretData(String secretData) {
this.secretData = secretData;
}

public String getHashedSaltedValue() {
return hashedSaltedValue;
public String getCredentialData() {
return credentialData;
}

public void setHashedSaltedValue(String hashedSaltedValue) {
this.hashedSaltedValue = hashedSaltedValue;
public void setCredentialData(String credentialData) {
this.credentialData = credentialData;
}

public String getSalt() {
return salt;
public Integer getPriority() {
return priority;
}

public void setSalt(String salt) {
this.salt = salt;
public void setPriority(Integer priority) {
this.priority = priority;
}

public Integer getHashIterations() {
return hashIterations;
public Long getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Long createdDate) {
this.createdDate = createdDate;
}

public void setHashIterations(Integer hashIterations) {
this.hashIterations = hashIterations;

public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}

public Boolean isTemporary() {
return temporary;
}

public void setTemporary(Boolean temporary) {
this.temporary = temporary;
}

public Integer getCounter() {
return counter;
}

public void setCounter(Integer counter) {
this.counter = counter;
}

public String getAlgorithm() {
return algorithm;
@Deprecated
public String getDevice() {
return device;
}

public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
@Deprecated
public String getHashedSaltedValue() {
return hashedSaltedValue;
}

public Integer getDigits() {
return digits;
@Deprecated
public String getSalt() {
return salt;
}

public void setDigits(Integer digits) {
this.digits = digits;
@Deprecated
public Integer getHashIterations() {
return hashIterations;
}

public Integer getPeriod() {
return period;
@Deprecated
public Integer getCounter() {
return counter;
}

public void setPeriod(Integer period) {
this.period = period;
@Deprecated
public String getAlgorithm() {
return algorithm;
}

public Long getCreatedDate() {
return createdDate;
@Deprecated
public Integer getDigits() {
return digits;
}

public void setCreatedDate(Long createdDate) {
this.createdDate = createdDate;
@Deprecated
public Integer getPeriod() {
return period;
}

@Deprecated
public MultivaluedHashMap<String, String> getConfig() {
return config;
}

public void setConfig(MultivaluedHashMap<String, String> config) {
this.config = config;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((algorithm == null) ? 0 : algorithm.hashCode());
result = prime * result + ((config == null) ? 0 : config.hashCode());
result = prime * result + ((counter == null) ? 0 : counter.hashCode());
result = prime * result + ((createdDate == null) ? 0 : createdDate.hashCode());
result = prime * result + ((device == null) ? 0 : device.hashCode());
result = prime * result + ((digits == null) ? 0 : digits.hashCode());
result = prime * result + ((hashIterations == null) ? 0 : hashIterations.hashCode());
result = prime * result + ((hashedSaltedValue == null) ? 0 : hashedSaltedValue.hashCode());
result = prime * result + ((period == null) ? 0 : period.hashCode());
result = prime * result + ((salt == null) ? 0 : salt.hashCode());
result = prime * result + ((userLabel == null) ? 0 : userLabel.hashCode());
result = prime * result + ((secretData == null) ? 0 : secretData.hashCode());
result = prime * result + ((credentialData == null) ? 0 : credentialData.hashCode());
result = prime * result + ((temporary == null) ? 0 : temporary.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
result = prime * result + ((priority == null) ? 0 : priority);
return result;
}

Expand All @@ -184,55 +198,25 @@ public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
CredentialRepresentation other = (CredentialRepresentation) obj;
if (algorithm == null) {
if (other.algorithm != null)
return false;
} else if (!algorithm.equals(other.algorithm))
return false;
if (config == null) {
if (other.config != null)
if (secretData == null) {
if (other.secretData != null)
return false;
} else if (!config.equals(other.config))
} else if (!secretData.equals(other.secretData))
return false;
if (counter == null) {
if (other.counter != null)
if (credentialData == null) {
if (other.credentialData != null)
return false;
} else if (!counter.equals(other.counter))
} else if (!credentialData.equals(other.credentialData))
return false;
if (createdDate == null) {
if (other.createdDate != null)
return false;
} else if (!createdDate.equals(other.createdDate))
return false;
if (device == null) {
if (other.device != null)
return false;
} else if (!device.equals(other.device))
return false;
if (digits == null) {
if (other.digits != null)
return false;
} else if (!digits.equals(other.digits))
return false;
if (hashIterations == null) {
if (other.hashIterations != null)
return false;
} else if (!hashIterations.equals(other.hashIterations))
return false;
if (hashedSaltedValue == null) {
if (other.hashedSaltedValue != null)
return false;
} else if (!hashedSaltedValue.equals(other.hashedSaltedValue))
return false;
if (period == null) {
if (other.period != null)
if (userLabel == null) {
if (other.userLabel != null)
return false;
} else if (!period.equals(other.period))
return false;
if (salt == null) {
if (other.salt != null)
return false;
} else if (!salt.equals(other.salt))
} else if (!userLabel.equals(other.userLabel))
return false;
if (temporary == null) {
if (other.temporary != null)
Expand All @@ -244,11 +228,23 @@ public boolean equals(Object obj) {
return false;
} else if (!type.equals(other.type))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
if (priority == null) {
if (other.priority != null)
return false;
} else if (!priority.equals(other.priority))
return false;
return true;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@
<module name="org.apache.httpcomponents"/>
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
<module name="javax.transaction.api"/>
<module name="com.fasterxml.jackson.core.jackson-core"/>
<module name="com.fasterxml.jackson.core.jackson-annotations"/>
<module name="com.fasterxml.jackson.core.jackson-databind"/>
<module name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider"/>
</dependencies>
</module>
Loading

0 comments on commit 4553234

Please sign in to comment.