diff --git a/identity/WritableCredential.cpp b/identity/WritableCredential.cpp
new file mode 100644
index 0000000..f58ec16
--- /dev/null
+++ b/identity/WritableCredential.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "WritableCredential"
+
+#include <android-base/logging.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <android/security/identity/ICredentialStore.h>
+
+#include <binder/IPCThreadState.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include "CredentialData.h"
+#include "Util.h"
+#include "WritableCredential.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::std::pair;
+
+using ::android::hardware::hidl_vec;
+
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+
+using ::android::hardware::identity::support::chunkVector;
+
+WritableCredential::WritableCredential(const string& dataPath, const string& credentialName,
+                                       const string& /*docType*/, size_t dataChunkSize,
+                                       sp<IWritableIdentityCredential> halBinder)
+    : dataPath_(dataPath), credentialName_(credentialName), dataChunkSize_(dataChunkSize),
+      halBinder_(halBinder) {}
+
+WritableCredential::~WritableCredential() {}
+
+Status WritableCredential::ensureAttestationCertificateExists(const vector<uint8_t>& challenge) {
+    vector<uint8_t> attestationCertificate;
+
+    if (!attestationCertificate_.empty()) {
+        return Status::ok();
+    }
+
+    Result result;
+    halBinder_->getAttestationCertificate(
+        challenge, [&](const Result& _result, const hidl_vec<uint8_t>& _attestationCertificate) {
+            result = _result;
+            attestationCertificate = _attestationCertificate;
+        });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "Error calling getAttestationCertificate()";
+        return halResultToGenericError(result);
+    }
+    attestationCertificate_ = attestationCertificate;
+    return Status::ok();
+}
+
+Status WritableCredential::getCredentialKeyCertificateChain(const vector<uint8_t>& challenge,
+                                                            vector<uint8_t>* _aidl_return) {
+
+    Status ensureStatus = ensureAttestationCertificateExists(challenge);
+    if (!ensureStatus.isOk()) {
+        return ensureStatus;
+    }
+
+    *_aidl_return = attestationCertificate_;
+    return Status::ok();
+}
+
+Status
+WritableCredential::personalize(const vector<AccessControlProfileParcel>& accessControlProfiles,
+                                const vector<EntryNamespaceParcel>& entryNamespaces,
+                                int64_t secureUserId, vector<uint8_t>* _aidl_return) {
+    Status ensureStatus = ensureAttestationCertificateExists({});
+    if (!ensureStatus.isOk()) {
+        return ensureStatus;
+    }
+
+    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
+    CredentialData data = CredentialData(dataPath_, callingUid, credentialName_);
+
+    // Note: The value 0 is used to convey that no user-authentication is needed for this
+    // credential. This is to allow creating credentials w/o user authentication on devices
+    // where Secure lock screen is not enabled.
+    data.setSecureUserId(secureUserId);
+
+    data.setAttestationCertificate(attestationCertificate_);
+
+    vector<uint16_t> entryCounts;
+    for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
+        entryCounts.push_back(ensParcel.entries.size());
+    }
+
+    Result result;
+    halBinder_->startPersonalization(accessControlProfiles.size(), entryCounts,
+                                     [&](const Result& _result) { result = _result; });
+    if (result.code != ResultCode::OK) {
+        return halResultToGenericError(result);
+    }
+
+    for (const AccessControlProfileParcel& acpParcel : accessControlProfiles) {
+        halBinder_->addAccessControlProfile(
+            acpParcel.id, acpParcel.readerCertificate, acpParcel.userAuthenticationRequired,
+            acpParcel.userAuthenticationTimeoutMillis, secureUserId,
+            [&](const Result& _result, const SecureAccessControlProfile& profile) {
+                data.addSecureAccessControlProfile(profile);
+                result = _result;
+            });
+        if (result.code != ResultCode::OK) {
+            return halResultToGenericError(result);
+        }
+    }
+
+    for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
+        for (const EntryParcel& eParcel : ensParcel.entries) {
+            vector<vector<uint8_t>> chunks = chunkVector(eParcel.value, dataChunkSize_);
+
+            vector<uint16_t> ids;
+            std::copy(eParcel.accessControlProfileIds.begin(),
+                      eParcel.accessControlProfileIds.end(), std::back_inserter(ids));
+
+            halBinder_->beginAddEntry(ids, ensParcel.namespaceName, eParcel.name,
+                                      eParcel.value.size(),
+                                      [&](const Result& _result) { result = _result; });
+            if (result.code != ResultCode::OK) {
+                return halResultToGenericError(result);
+            }
+
+            vector<vector<uint8_t>> encryptedChunks;
+            for (const auto& chunk : chunks) {
+                halBinder_->addEntryValue(
+                    chunk, [&](const Result& _result, const hidl_vec<uint8_t>& encryptedContent) {
+                        result = _result;
+                        encryptedChunks.push_back(encryptedContent);
+                    });
+                if (result.code != ResultCode::OK) {
+                    return halResultToGenericError(result);
+                }
+            }
+            EntryData eData;
+            eData.size = eParcel.value.size();
+            eData.accessControlProfileIds = std::move(ids);
+            eData.encryptedChunks = std::move(encryptedChunks);
+            data.addEntryData(ensParcel.namespaceName, eParcel.name, eData);
+        }
+    }
+
+    vector<uint8_t> credentialData;
+    vector<uint8_t> proofOfProvisioningSignature;
+    halBinder_->finishAddingEntries([&](const Result& _result,
+                                        const hidl_vec<uint8_t>& _credentialData,
+                                        const hidl_vec<uint8_t>& _proofOfProvisioningSignature) {
+        data.setCredentialData(_credentialData);
+        result = _result;
+        credentialData = _credentialData;
+        proofOfProvisioningSignature = _proofOfProvisioningSignature;
+    });
+    if (result.code != ResultCode::OK) {
+        return halResultToGenericError(result);
+    }
+
+    if (!data.saveToDisk()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error saving credential data to disk");
+    }
+
+    *_aidl_return = proofOfProvisioningSignature;
+    return Status::ok();
+}
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
