/* * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. * * Copyright (c) 2014, Gluu */ package org.xdi.oxauth.model.fido.u2f; import java.io.Serializable; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Date; import org.gluu.site.ldap.persistence.annotation.LdapAttribute; import org.gluu.site.ldap.persistence.annotation.LdapEntry; import org.gluu.site.ldap.persistence.annotation.LdapJsonObject; import org.gluu.site.ldap.persistence.annotation.LdapObjectClass; import org.xdi.ldap.model.BaseEntry; import org.xdi.oxauth.exception.fido.u2f.InvalidDeviceCounterException; import org.xdi.oxauth.model.fido.u2f.exception.BadInputException; import org.xdi.oxauth.model.fido.u2f.protocol.DeviceData; import org.xdi.oxauth.model.util.Base64Util; /** * U2F Device registration * * @author Yuriy Movchan Date: 05/14/2015 */ @LdapEntry(sortBy = "creationDate") @LdapObjectClass(values = {"top", "oxDeviceRegistration"}) public class DeviceRegistration extends BaseEntry implements Serializable { private static final long serialVersionUID = -4542931562244920584L; @LdapAttribute(ignoreDuringUpdate = true, name = "oxId") private String id; @LdapAttribute private String displayName; @LdapAttribute private String description; @LdapJsonObject @LdapAttribute(name = "oxDeviceRegistrationConf") private DeviceRegistrationConfiguration deviceRegistrationConfiguration; @LdapAttribute(name = "oxCounter") private long counter; @LdapAttribute(name = "oxStatus") private DeviceRegistrationStatus status; @LdapAttribute(name = "oxApplication") private String application; @LdapAttribute(name = "oxDeviceKeyHandle") private String keyHandle; @LdapAttribute(name = "oxDeviceHashCode") private Integer keyHandleHashCode; @LdapJsonObject @LdapAttribute(name = "oxDeviceData") private DeviceData deviceData; @LdapAttribute(name = "creationDate") private Date creationDate; @LdapAttribute(name = "oxLastAccessTime") private Date lastAccessTime; public DeviceRegistration() {} public DeviceRegistration(String keyHandle, String publicKey, String attestationCert, long counter, DeviceRegistrationStatus status, String application, Integer keyHandleHashCode, Date creationDate) { this.deviceRegistrationConfiguration = new DeviceRegistrationConfiguration(publicKey, attestationCert); this.counter = counter; this.status = status; this.application = application; this.keyHandle = keyHandle; this.keyHandleHashCode = keyHandleHashCode; this.creationDate = creationDate; } public DeviceRegistration(String keyHandle, String publicKey, X509Certificate attestationCert, long counter) throws BadInputException { this.keyHandle = keyHandle; try { String attestationCertDecoded = Base64Util.base64urlencode(attestationCert.getEncoded()); this.deviceRegistrationConfiguration = new DeviceRegistrationConfiguration(publicKey, attestationCertDecoded); } catch (CertificateEncodingException e) { throw new BadInputException("Malformed attestation certificate", e); } this.counter = counter; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public DeviceRegistrationConfiguration getDeviceRegistrationConfiguration() { return deviceRegistrationConfiguration; } public void setDeviceRegistrationConfiguration(DeviceRegistrationConfiguration deviceRegistrationConfiguration) { this.deviceRegistrationConfiguration = deviceRegistrationConfiguration; } public long getCounter() { return counter; } public void setCounter(long counter) { this.counter = counter; } public DeviceRegistrationStatus getStatus() { return status; } public void setStatus(DeviceRegistrationStatus status) { this.status = status; } public String getApplication() { return application; } public void setApplication(String application) { this.application = application; } public String getKeyHandle() { return keyHandle; } public void setKeyHandle(String keyHandle) { this.keyHandle = keyHandle; } public Integer getKeyHandleHashCode() { return keyHandleHashCode; } public void setKeyHandleHashCode(Integer keyHandleHashCode) { this.keyHandleHashCode = keyHandleHashCode; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } public DeviceData getDeviceData() { return deviceData; } public void setDeviceData(DeviceData deviceData) { this.deviceData = deviceData; } public Date getLastAccessTime() { return lastAccessTime; } public void setLastAccessTime(Date lastAccessTime) { this.lastAccessTime = lastAccessTime; } public boolean isCompromised() { return DeviceRegistrationStatus.COMPROMISED == this.status; } public void markCompromised() { this.status = DeviceRegistrationStatus.COMPROMISED; } public void checkAndUpdateCounter(long clientCounter) throws InvalidDeviceCounterException { if (clientCounter <= counter) { markCompromised(); throw new InvalidDeviceCounterException(this); } counter = clientCounter; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("DeviceRegistration [id=").append(id).append(", displayName=").append(displayName).append(", description=") .append(description).append(", deviceRegistrationConfiguration=").append(deviceRegistrationConfiguration) .append(", counter=").append(counter).append(", status=").append(status).append(", application=").append(application) .append(", keyHandle=").append(keyHandle).append(", keyHandleHashCode=").append(keyHandleHashCode).append(", deviceData=") .append(deviceData).append(", creationDate=").append(creationDate).append(", lastAccessTime=").append(lastAccessTime) .append("]"); return builder.toString(); } }