Sample code for 30+ languages & platforms
Zig Requires Chilkat v11.0.0+

Azure Key Vault Import Certificate

See more Azure Key Vault Examples

Imports a certificate into a specified Azure key vault.

Imports an existing valid certificate, containing a private key, into Azure Key Vault. The certificate to be imported can be in either PFX or PEM format. If the certificate is in PEM format the PEM file must contain the key as well as x509 certificates. Key Vault will only accept a key in PKCS#8 format.

Chilkat Zig Downloads

Zig
const std = @import("std");
const chilkat = @import("chilkat");

pub fn main(init: std.process.Init) !void {
    const alloc = init.arena.allocator();

    // This requires the Chilkat API to have been previously unlocked.
    // See Global Unlock Sample for sample code.

    // See Azure Key Vault Get Certificates for a more detailed explanation
    // for how Chilkat is automatically getting the OAuth2 access token for your application.

    // Provide information needed for Chilkat to automatically get an OAuth2 access token as needed.
    const json = try chilkat.JsonObject.init();
    defer json.deinit();
    json.updateString("client_id", "APP_ID") catch {};
    json.updateString("client_secret", "APP_PASSWORD") catch {};
    json.updateString("resource", "https://vault.azure.net") catch {};
    json.updateString("token_endpoint", "https://login.microsoftonline.com/TENANT_ID/oauth2/token") catch {};

    // Note: This example is using a relative file path.  You can also specify a full file path, such as "C:/someDir/myCertAndKey.pfx"
    // or a file path the makes sense on non-Windows operating systems..
    const pfx_file_path = "qa_data/pfx/myCertAndKey.pfx";

    // Load the PFX file to be imported to the Azure Key Vault.
    const bd_pfx = try chilkat.BinData.init();
    defer bd_pfx.deinit();
    bd_pfx.loadFile(pfx_file_path) catch {
        std.debug.print("Failed to load the PFX file.\n", .{});
        return;
    };

    // We'll be sending a POST request like this:

    // POST https://myvault.vault.azure.net//certificates/importCert01/import?api-version=7.4
    //
    // {
    //   "value": "MIIJ...",
    //   "pwd": "123",
    //   "policy": {
    //     "key_props": {
    //       "exportable": true,
    //       "kty": "RSA",
    //       "key_size": 2048,
    //       "reuse_key": false
    //     },
    //     "secret_props": {
    //       "contentType": "application/x-pkcs12"
    //     }
    //   }
    // }

    // Also load the PFX into the Chilkat certificate object so we can get
    // information about the key type and size.
    const cert = try chilkat.Cert.init();
    defer cert.deinit();
    cert.loadPfxFile(pfx_file_path, "pfx_password") catch {
        std.debug.print("{s}\n", .{try cert.getLastErrorText(alloc)});
        return;
    };

    const priv_key = try chilkat.PrivateKey.init();
    defer priv_key.deinit();
    cert.getPrivateKey(priv_key) catch {
        std.debug.print("{s}\n", .{try cert.getLastErrorText(alloc)});
        return;
    };

    // Get the private key as a JWK so we can get information about it..
    const jwk = try chilkat.JsonObject.init();
    defer jwk.deinit();
    jwk.load(try priv_key.getJwk(alloc)) catch {};

    // Get the key type
    const sb_kty = try chilkat.StringBuilder.init();
    defer sb_kty.deinit();
    sb_kty.append(try jwk.stringOf(alloc, "kty")) catch {};

    // If this is an EC key, get the curve name
    const sb_curve = try chilkat.StringBuilder.init();
    defer sb_curve.deinit();
    if (jwk.hasMember("crv")) {
        sb_curve.append(try jwk.stringOf(alloc, "crv")) catch {};
    }

    // Build the JSON that will be the body of the HTTP POST.
    const json_body = try chilkat.JsonObject.init();
    defer json_body.deinit();
    json_body.updateString("value", try bd_pfx.getEncoded(alloc, "base64")) catch {};
    json_body.updateString("pwd", "pfx_password") catch {};
    json_body.updateBool("policy.key_props.exportable", true) catch {};
    json_body.updateString("policy.key_props.kty", try sb_kty.getAsString(alloc)) catch {};
    if (sb_kty.contentsEqual("RSA", false)) {
        json_body.updateInt("policy.key_props.key_size", priv_key.getBitLength()) catch {};
    }

    if (sb_kty.contentsEqual("EC", false)) {
        json_body.updateString("policy.key_props.crv", try sb_curve.getAsString(alloc)) catch {};
    }

    json_body.updateBool("policy.key_props.reuse_key", false) catch {};
    json_body.updateString("policy.secret_props.contentType", "application/x-pkcs12") catch {};

    const http = try chilkat.Http.init();
    defer http.deinit();

    // Instead of providing an actual access token, we give Chilkat the information that allows it to
    // automatically fetch the access token using the OAuth2 client credentials flow.
    http.setAuthToken(try json.emit(alloc));

    // Choose anything to be the name of your imported certificate.
    http.setUrlVar("certificateName", "importCert01") catch {};
    // Note: Replace "VAULT_NAME" with the name of your Azure key vault.
    const url = "https://VAULT_NAME.vault.azure.net/certificates/{$certificateName}/import?api-version=7.4";
    const resp = try chilkat.HttpResponse.init();
    defer resp.deinit();
    http.httpJson("POST", url, json_body, "application/json", resp) catch {
        std.debug.print("{s}\n", .{try http.getLastErrorText(alloc)});
        return;
    };

    const status_code = resp.getStatusCode();

    const json_resp = try chilkat.JsonObject.init();
    defer json_resp.deinit();
    resp.getBodyJson(json_resp) catch {};

    json_resp.setEmitCompact(false);
    std.debug.print("{s}\n", .{try json_resp.emit(alloc)});

    if (status_code != 200) {
        std.debug.print("Failed.\n", .{});
        return;
    }

    // A successful JSON response looks like this:

    // {
    //   "id": "https://kvchilkat.vault.azure.net/certificates/importCert01/7140c8755ed14839b5d86a9f7e7f0497",
    //   "kid": "https://kvchilkat.vault.azure.net/keys/importCert01/7140c8755ed14839b5d86a9f7e7f0497",
    //   "sid": "https://kvchilkat.vault.azure.net/secrets/importCert01/7140c8755ed14839b5d86a9f7e7f0497",
    //   "x5t": "I_e3776K5Q_6PN1HHvJoI2ZGQRQ",
    //   "cer": "MIIG ... jTsi7yIY=",
    //   "attributes": {
    //     "enabled": true,
    //     "nbf": 1633996800,
    //     "exp": 1728691199,
    //     "created": 1697411128,
    //     "updated": 1697411128,
    //     "recoveryLevel": "CustomizedRecoverable+Purgeable",
    //     "recoverableDays": 7
    //   },
    //   "policy": {
    //     "id": "https://kvchilkat.vault.azure.net/certificates/importCert01/policy",
    //     "key_props": {
    //       "exportable": true,
    //       "kty": "RSA",
    //       "key_size": 4096,
    //       "reuse_key": false
    //     },
    //     "secret_props": {
    //       "contentType": "application/x-pkcs12"
    //     },
    //     "x509_props": {
    //       "subject": "CN=\"Chilkat Software, Inc.\", O=\"Chilkat Software, Inc.\", S=Illinois, C=US",
    //       "ekus": [
    //         "1.3.6.1.5.5.7.3.3"
    //       ],
    //       "key_usage": [
    //         "digitalSignature"
    //       ],
    //       "validity_months": 37,
    //       "basic_constraints": {
    //         "ca": false
    //       }
    //     },
    //     "lifetime_actions": [
    //       {
    //         "trigger": {
    //           "lifetime_percentage": 80
    //         },
    //         "action": {
    //           "action_type": "EmailContacts"
    //         }
    //       }
    //     ],
    //     "issuer": {
    //       "name": "Unknown"
    //     },
    //     "attributes": {
    //       "enabled": true,
    //       "created": 1697411128,
    //       "updated": 1697411128
    //     }
    //   }
    // }

    // Use this online tool to generate parsing code from sample JSON:
    // Generate Parsing Code from JSON

    var str_val: [:0]const u8 = "";
    var lifetime_percentage: i32 = 0;
    var action_type: [:0]const u8 = "";

    var id: [:0]const u8 = try json_resp.stringOf(alloc, "id");
    _ = try json_resp.stringOf(alloc, "kid");
    _ = try json_resp.stringOf(alloc, "sid");
    _ = try json_resp.stringOf(alloc, "x5t");
    _ = try json_resp.stringOf(alloc, "cer");
    _ = json_resp.boolOf("attributes.enabled");
    _ = json_resp.intOf("attributes.nbf");
    _ = json_resp.intOf("attributes.exp");
    _ = json_resp.intOf("attributes.created");
    _ = json_resp.intOf("attributes.updated");
    _ = try json_resp.stringOf(alloc, "attributes.recoveryLevel");
    _ = json_resp.intOf("attributes.recoverableDays");
    id = try json_resp.stringOf(alloc, "policy.id");
    _ = json_resp.boolOf("policy.key_props.exportable");
    _ = try json_resp.stringOf(alloc, "policy.key_props.kty");
    _ = json_resp.intOf("policy.key_props.key_size");
    _ = json_resp.boolOf("policy.key_props.reuse_key");
    _ = try json_resp.stringOf(alloc, "policy.secret_props.contentType");
    _ = try json_resp.stringOf(alloc, "policy.x509_props.subject");
    _ = json_resp.intOf("policy.x509_props.validity_months");
    _ = json_resp.boolOf("policy.x509_props.basic_constraints.ca");
    _ = try json_resp.stringOf(alloc, "policy.issuer.name");
    _ = json_resp.boolOf("policy.attributes.enabled");
    _ = json_resp.intOf("policy.attributes.created");
    _ = json_resp.intOf("policy.attributes.updated");
    var i: i32 = 0;
    var count_i: i32 = json_resp.sizeOfArray("policy.x509_props.ekus");
    while (i < count_i) {
        json_resp.setI(i);
        str_val = try json_resp.stringOf(alloc, "policy.x509_props.ekus[i]");
        i = i + 1;
    }

    i = 0;
    count_i = json_resp.sizeOfArray("policy.x509_props.key_usage");
    while (i < count_i) {
        json_resp.setI(i);
        str_val = try json_resp.stringOf(alloc, "policy.x509_props.key_usage[i]");
        i = i + 1;
    }

    i = 0;
    count_i = json_resp.sizeOfArray("policy.lifetime_actions");
    while (i < count_i) {
        json_resp.setI(i);
        lifetime_percentage = json_resp.intOf("policy.lifetime_actions[i].trigger.lifetime_percentage");
        action_type = try json_resp.stringOf(alloc, "policy.lifetime_actions[i].action.action_type");
        i = i + 1;
    }
}