protected override async Task OnExecute() { // Open the store var store = await OpenSecretStore(); // Load the cert file var cert = new X509Certificate2(File, String.Empty, X509KeyStorageFlags.Exportable); if (!cert.HasPrivateKey) { await Console.WriteErrorLine(Strings.Secrets_StoreCertCommand_CertificateHasNoPrivateKey); return; } // Save to a string string data = Convert.ToBase64String(cert.Export(X509ContentType.Pkcs12, String.Empty)); // Determine expiry var expiresAt = cert.NotAfter; // Save the certificate secret // Cert thumbprints are universal, no datacenter-scope needed var certKey = new SecretName("cert:" + cert.Thumbprint, null); await Console.WriteInfoLine(Strings.Secrets_StoreCertCommand_SavingCertificate, certKey.Name, expiresAt); if (!WhatIf) { var secret = new Secret(certKey, data, DateTime.UtcNow, expiresAt, SecretType.Certificate); await store.Write(secret, "nucmd storecert"); } await Console.WriteInfoLine(Strings.Secrets_StoreCertCommand_SavingCertificateReference, Key, expiresAt); if (!WhatIf) { var secret = new Secret(new SecretName(Key, Datacenter), certKey.ToString(), DateTime.UtcNow, expiresAt, SecretType.Link); await store.Write(secret, "nucmd storecert"); } }
protected override async Task OnExecute() { // Open the store var store = await OpenSecretStore(); if (String.IsNullOrEmpty(Value)) { if (Generate) { Value = Utils.GeneratePassword(timestamped: true); } else { var secureValue = await Console.PromptForPassword(String.Format( CultureInfo.CurrentCulture, Strings.Secrets_SetCommand_EnterValue, Key)); // PromptForPassword returns a SecureString, but we need it to be unsecure for serialization unfortunately :( IntPtr p = IntPtr.Zero; try { p = Marshal.SecureStringToGlobalAllocUnicode(secureValue); Value = Marshal.PtrToStringUni(p); } finally { Marshal.ZeroFreeGlobalAllocUnicode(p); } } } if (ExpiresIn != null) { ExpiresAt = DateTime.Now + ExpiresIn.Value; } if (ExpiresAt != null) { ExpiresAt = ExpiresAt.Value.ToUniversalTime(); } // Create the secret to set var secret = new Secret(new SecretName(Key, Datacenter), Value, DateTime.UtcNow, ExpiresAt, Type ?? SecretType.Password); if (ExpiresAt == null) { await Console.WriteInfoLine(Strings.Secrets_SetCommand_Writing, Key); } else { await Console.WriteInfoLine(Strings.Secrets_SetCommand_WritingWithExpiry, Key, ExpiresAt.Value); } if (!WhatIf) { await store.Write(secret, "nucmd set"); } await Console.WriteInfoLine(Strings.Secrets_SetCommand_Written, Key); }
public abstract Task Write(Secret secret, string clientOperation);
protected virtual X509Certificate2 ReadCertificate(Secret secret) { // Write to our own temp file because the X509Certificate2 ctor // that takes a byte array writes a temp file and then never cleans it up string temp = Path.GetTempFileName(); X509Certificate2 cert; try { File.WriteAllBytes(temp, Convert.FromBase64String(secret.Value)); cert = new X509Certificate2(temp, String.Empty); } finally { if (File.Exists(temp)) { File.Delete(temp); } } return cert; }
internal void Update(Secret secret) { Value = secret.Value; Type = secret.Type; ExpiryUtc = secret.ExpiryUtc; }
public override async Task Write(Secret secret, string clientOperation) { // Try to read the secret var existingSecret = await UnauditedReadSecret(secret.Name, GetFileName(secret.Name)); // Try to undelete the secret, in case a deleted form exists if (existingSecret == null && await Undelete(secret.Name, clientOperation)) { existingSecret = await UnauditedReadSecret(secret.Name, GetFileName(secret.Name)); } if (existingSecret != null) { // Copy the new data and add audit records existingSecret.AddAuditEntry(await SecretAuditEntry.CreateForLocalUser(clientOperation, SecretAuditAction.Changed, existingSecret.Value)); existingSecret.Update(secret); // Now resave the existing secret instead secret = existingSecret; } else { // Add an audit record secret.AddAuditEntry(await SecretAuditEntry.CreateForLocalUser(clientOperation, SecretAuditAction.Created)); } // Write the secret await UnauditedWriteSecret(secret); }
private Task UnauditedWriteSecret(Secret secret) { // Generate the name of the file string secretFile = GetFileName(secret.Name); // Write the file var protector = CreateProtector(secret.Name); return DpapiSecretStoreProvider.WriteSecretFile(secretFile, JsonFormat.Serialize(secret), protector); }