-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[INJIMOB-1588] mso_mdoc VC support for mock plugin (#51)
* [INJIMOB-1588] add mock mdoc Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] Get issuer certificate + keypair from local p12 file Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] Populate mock mDoc from DB Build mdoc from mock DB using the cached transaction and in case of any issue give hardcoded set of data Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1788] generate mdoc Library used - open-wallet-foundation-labs/identity-credetial Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] produce mso_mdoc VC from individualId provided Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] read crypto details for signing mso_mdoc vc Other changes: removing unused classes/ debug logs Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] remove debug logs , optimize imports Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] remove unused declared dependencies Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] add respository for identity-credential dependency Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] update snapshot version Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] remove debug logs Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] refactor unused fields, renaming Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] git ignore .DS_Store Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] perform base64 url safe encoding Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] refactor variable name Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] Get issuer and ca cryto details from config property Signed-off-by: KiruthikaJeyashankar <[email protected]> * [INJIMOB-1588] revert IDE format changes Signed-off-by: KiruthikaJeyashankar <[email protected]> --------- Signed-off-by: KiruthikaJeyashankar <[email protected]>
- Loading branch information
1 parent
fa0aee7
commit 4448c7b
Showing
9 changed files
with
423 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,3 +32,4 @@ target/ | |
.setting/ | ||
.mvn/ | ||
.project/ | ||
*.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
mock-certify-plugin/src/main/java/io/mosip/certify/mock/integration/mocks/MdocGenerator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package io.mosip.certify.mock.integration.mocks | ||
|
||
import co.nstant.`in`.cbor.CborBuilder | ||
import co.nstant.`in`.cbor.CborEncoder | ||
import co.nstant.`in`.cbor.model.DataItem | ||
import com.android.identity.credential.NameSpacedData | ||
import com.android.identity.internal.Util | ||
import com.android.identity.mdoc.mso.MobileSecurityObjectGenerator | ||
import com.android.identity.mdoc.util.MdocUtil | ||
import com.android.identity.util.Timestamp | ||
import io.mosip.certify.util.* | ||
import java.io.ByteArrayOutputStream | ||
import io.mosip.certify.util.IssuerKeyPairAndCertificate | ||
import java.util.* | ||
|
||
|
||
class MdocGenerator { | ||
companion object { | ||
const val NAMESPACE: String = "org.iso.18013.5.1" | ||
const val DOCTYPE: String = "$NAMESPACE.mDL" | ||
const val DIGEST_ALGORITHM = "SHA-256" | ||
const val ECDSA_ALGORITHM = "SHA256withECDSA" | ||
const val SEED = 42L | ||
} | ||
|
||
fun generate( | ||
data: MutableMap<String, out Any>, | ||
holderId: String, | ||
caKeyAndCertificate: String, | ||
issuerKeyAndCertificate: String | ||
): String? { | ||
val issuerKeyPairAndCertificate: IssuerKeyPairAndCertificate? = readKeypairAndCertificates( | ||
caKeyAndCertificate,issuerKeyAndCertificate | ||
) | ||
if(issuerKeyPairAndCertificate == null) { | ||
throw RuntimeException("Unable to load Crypto details") | ||
} | ||
val devicePublicKey = JwkToKeyConverter().convertToPublicKey(holderId.replace("did:jwk:", "")) | ||
val issuerKeypair = issuerKeyPairAndCertificate.issuerKeypair() | ||
|
||
val nameSpacedDataBuilder: NameSpacedData.Builder = NameSpacedData.Builder() | ||
data.keys.forEach { key -> | ||
nameSpacedDataBuilder.putEntryString(NAMESPACE, key, data[key].toString()) | ||
} | ||
val nameSpacedData: NameSpacedData = | ||
nameSpacedDataBuilder | ||
.build() | ||
val generatedIssuerNameSpaces: MutableMap<String, MutableList<ByteArray>> = | ||
MdocUtil.generateIssuerNameSpaces(nameSpacedData, Random(SEED), 16) | ||
val calculateDigestsForNameSpace = | ||
MdocUtil.calculateDigestsForNameSpace(NAMESPACE, generatedIssuerNameSpaces, DIGEST_ALGORITHM) | ||
|
||
val mobileSecurityObjectGenerator = MobileSecurityObjectGenerator(DIGEST_ALGORITHM, NAMESPACE, devicePublicKey) | ||
mobileSecurityObjectGenerator.addDigestIdsForNamespace(NAMESPACE, calculateDigestsForNameSpace) | ||
val expirationTime: Long = kotlinx.datetime.Instant.Companion.DISTANT_FUTURE.toEpochMilliseconds() | ||
mobileSecurityObjectGenerator.setValidityInfo( | ||
Timestamp.now(), | ||
Timestamp.now(), | ||
Timestamp.ofEpochMilli(expirationTime), | ||
null | ||
) | ||
val mso: ByteArray = mobileSecurityObjectGenerator.generate() | ||
|
||
val coseSign1Sign: DataItem = Util.coseSign1Sign( | ||
issuerKeypair.private, | ||
ECDSA_ALGORITHM, | ||
mso.copyOf(), | ||
null, | ||
listOf(issuerKeyPairAndCertificate.caCertificate(), issuerKeyPairAndCertificate.issuerCertificate()) | ||
) | ||
|
||
return construct(generatedIssuerNameSpaces, coseSign1Sign) | ||
} | ||
|
||
@Throws(Exception::class) | ||
private fun readKeypairAndCertificates(caKeyAndCertificate: String,issuerKeyAndCertificate: String): IssuerKeyPairAndCertificate? { | ||
val pkcS12Reader = PKCS12Reader() | ||
val caDetails: KeyPairAndCertificate = pkcS12Reader.extract(caKeyAndCertificate) | ||
val issuerDetails: KeyPairAndCertificate = pkcS12Reader.extract(issuerKeyAndCertificate) | ||
if (issuerDetails != null && caDetails != null) { | ||
return IssuerKeyPairAndCertificate( | ||
issuerDetails.keyPair, | ||
issuerDetails.certificate, | ||
caDetails.certificate | ||
) | ||
} | ||
return null | ||
} | ||
|
||
private fun construct(nameSpaces: MutableMap<String, MutableList<ByteArray>>, issuerAuth: DataItem): String? { | ||
val mDoc = MDoc(DOCTYPE, IssuerSigned(nameSpaces, issuerAuth)) | ||
val cbor = mDoc.toCBOR() | ||
return Base64.getUrlEncoder().encodeToString(cbor) | ||
} | ||
} | ||
|
||
data class MDoc(val docType: String, val issuerSigned: IssuerSigned) { | ||
fun toCBOR(): ByteArray { | ||
val byteArrayOutputStream = ByteArrayOutputStream() | ||
CborEncoder(byteArrayOutputStream).encode( | ||
CborBuilder().addMap() | ||
.put("docType", docType) | ||
.put(CBORConverter.toDataItem("issuerSigned"), CBORConverter.toDataItem(issuerSigned.toMap())) | ||
.end() | ||
.build() | ||
) | ||
return byteArrayOutputStream.toByteArray() | ||
|
||
} | ||
} | ||
|
||
data class IssuerSigned(val nameSpaces: MutableMap<String, MutableList<ByteArray>>, val issuerAuth: DataItem) { | ||
fun toMap(): Map<String, Any> { | ||
return buildMap { | ||
put("nameSpaces", CBORConverter.toDataItem(nameSpaces)) | ||
put("issuerAuth", issuerAuth) | ||
} | ||
} | ||
} |
Oops, something went wrong.