Skip to content

Commit

Permalink
Merge PR #71.
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamVe committed Mar 25, 2022
2 parents 687df01 + 9547995 commit e11ca5b
Show file tree
Hide file tree
Showing 13 changed files with 514 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.yubico.authenticator.api
import com.yubico.authenticator.MainViewModel
import com.yubico.authenticator.api.Pigeon.OathApi
import com.yubico.authenticator.api.Pigeon.Result
import com.yubico.authenticator.api.Pigeon.UnlockResponse

class OathApiImpl(private val viewModel: MainViewModel) : OathApi {

Expand All @@ -13,7 +14,7 @@ class OathApiImpl(private val viewModel: MainViewModel) : OathApi {
override fun unlock(
password: String,
remember: Boolean,
result: Result<Boolean>
result: Result<UnlockResponse>
) {
viewModel.unlockOathSession(password, remember, result)
}
Expand Down
75 changes: 72 additions & 3 deletions android/app/src/main/java/com/yubico/authenticator/api/Pigeon.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,88 @@
@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})
public class Pigeon {

/** Generated class from Pigeon that represents data sent in messages. */
public static class UnlockResponse {
private @Nullable Boolean isUnlocked;
public @Nullable Boolean getIsUnlocked() { return isUnlocked; }
public void setIsUnlocked(@Nullable Boolean setterArg) {
this.isUnlocked = setterArg;
}

private @Nullable Boolean isRemembered;
public @Nullable Boolean getIsRemembered() { return isRemembered; }
public void setIsRemembered(@Nullable Boolean setterArg) {
this.isRemembered = setterArg;
}

public static class Builder {
private @Nullable Boolean isUnlocked;
public @NonNull Builder setIsUnlocked(@Nullable Boolean setterArg) {
this.isUnlocked = setterArg;
return this;
}
private @Nullable Boolean isRemembered;
public @NonNull Builder setIsRemembered(@Nullable Boolean setterArg) {
this.isRemembered = setterArg;
return this;
}
public @NonNull UnlockResponse build() {
UnlockResponse pigeonReturn = new UnlockResponse();
pigeonReturn.setIsUnlocked(isUnlocked);
pigeonReturn.setIsRemembered(isRemembered);
return pigeonReturn;
}
}
@NonNull Map<String, Object> toMap() {
Map<String, Object> toMapResult = new HashMap<>();
toMapResult.put("isUnlocked", isUnlocked);
toMapResult.put("isRemembered", isRemembered);
return toMapResult;
}
static @NonNull UnlockResponse fromMap(@NonNull Map<String, Object> map) {
UnlockResponse pigeonResult = new UnlockResponse();
Object isUnlocked = map.get("isUnlocked");
pigeonResult.setIsUnlocked((Boolean)isUnlocked);
Object isRemembered = map.get("isRemembered");
pigeonResult.setIsRemembered((Boolean)isRemembered);
return pigeonResult;
}
}

public interface Result<T> {
void success(T result);
void error(Throwable error);
}
private static class OathApiCodec extends StandardMessageCodec {
public static final OathApiCodec INSTANCE = new OathApiCodec();
private OathApiCodec() {}
@Override
protected Object readValueOfType(byte type, ByteBuffer buffer) {
switch (type) {
case (byte)128:
return UnlockResponse.fromMap((Map<String, Object>) readValue(buffer));

default:
return super.readValueOfType(type, buffer);

}
}
@Override
protected void writeValue(ByteArrayOutputStream stream, Object value) {
if (value instanceof UnlockResponse) {
stream.write(128);
writeValue(stream, ((UnlockResponse) value).toMap());
} else
{
super.writeValue(stream, value);
}
}
}

/** Generated interface from Pigeon that represents a handler of messages from Flutter.*/
public interface OathApi {
void reset(Result<Void> result);
void unlock(@NonNull String password, @NonNull Boolean remember, Result<Boolean> result);
void unlock(@NonNull String password, @NonNull Boolean remember, Result<UnlockResponse> result);
void setPassword(@Nullable String currentPassword, @NonNull String newPassword, Result<Void> result);
void unsetPassword(@NonNull String currentPassword, Result<Void> result);
void forgetPassword(Result<Void> result);
Expand Down Expand Up @@ -96,8 +165,8 @@ public void error(Throwable error) {
if (rememberArg == null) {
throw new NullPointerException("rememberArg unexpectedly null.");
}
Result<Boolean> resultCallback = new Result<Boolean>() {
public void success(Boolean result) {
Result<UnlockResponse> resultCallback = new Result<UnlockResponse>() {
public void success(UnlockResponse result) {
wrapped.put("result", result);
reply.reply(wrapped);
}
Expand Down
70 changes: 70 additions & 0 deletions android/app/src/main/kotlin/com/yubico/authenticator/KeyManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2022, Yubico AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

package com.yubico.authenticator

import com.yubico.authenticator.keystore.KeyProvider
import com.yubico.yubikit.oath.AccessKey

class KeyManager(private val permStore: KeyProvider, private val memStore: KeyProvider) {

/**
* @return true if this deviceId is stored in permanent KeyStore
*/
fun isRemembered(deviceId: String) = permStore.hasKey(deviceId)

fun getKey(deviceId: String): AccessKey? {
return if (permStore.hasKey(deviceId)) {
permStore.getKey(deviceId)
} else {
memStore.getKey(deviceId)
}
}

fun addKey(deviceId: String, secret: ByteArray, remember: Boolean) {
if (remember) {
memStore.removeKey(deviceId)
permStore.putKey(deviceId, secret)
} else {
permStore.removeKey(deviceId)
memStore.putKey(deviceId, secret)
}
}

fun removeKey(deviceId: String) {
memStore.removeKey(deviceId)
permStore.removeKey(deviceId)
}

fun clearAll() {
memStore.clearAll()
permStore.clearAll()
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.yubico.authenticator

import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels
Expand Down

0 comments on commit e11ca5b

Please sign in to comment.