/// <summary> /// Encrypt SD data with exchange key. /// </summary> /// <param name="plaintextList"></param> /// <param name="cert">Exchange key</param> /// <returns></returns> public SecurityDomainRestoreData EncryptForRestore(PlaintextList plaintextList, X509Certificate2 cert) { try { SecurityDomainRestoreData securityDomainRestoreData = new SecurityDomainRestoreData(); securityDomainRestoreData.EncData.kdf = "sp108_kdf"; byte[] master_key = Utils.GetRandom(32); foreach (Plaintext p in plaintextList.list) { Datum datum = new Datum(); HMACSHA512 hmac = new HMACSHA512(); byte[] enc_key = KDF.sp800_108(master_key, p.tag, "", hmac, 512); datum.tag = p.tag; JWE jwe = new JWE(); jwe.Encrypt(enc_key, p.plaintext, "A256CBC-HS512", p.tag); datum.compact_jwe = jwe.EncodeCompact(); securityDomainRestoreData.EncData.data.Add(datum); } // Now go make the wrapped key JWE jwe_wrapped = new JWE(); jwe_wrapped.Encrypt(cert, master_key); securityDomainRestoreData.WrappedKey.enc_key = jwe_wrapped.EncodeCompact(); securityDomainRestoreData.WrappedKey.x5t_256 = Base64UrlEncoder.Encode(Utils.Sha256Thumbprint(cert)); return(securityDomainRestoreData); } catch (Exception ex) { throw new Exception("Failed to encrypt security domain data for restoring.", ex); } }
/// <summary> /// Upload security domain data and initiate restoring. /// </summary> /// <param name="hsmName"></param> /// <param name="securityDomainData">Encrypted by exchange key</param> public void RestoreSecurityDomain(string hsmName, SecurityDomainRestoreData securityDomainData, CancellationToken cancellationToken) { string securityDomain = JsonConvert.SerializeObject(new SecurityDomainWrapper { value = JsonConvert.SerializeObject(securityDomainData) }); try { var httpRequest = CreateRequest(HttpMethod.Post, hsmName, $"/{_securityDomain}/upload", new StringContent(securityDomain)); PollAsyncOperation(httpRequest, cancellationToken); } catch (Exception ex) { throw new Exception(Resources.RestoreSecurityDomainFailure, ex); } }
/// <summary> /// Upload security domain data and initiate restoring. /// </summary> /// <param name="hsmName"></param> /// <param name="securityDomainData">Encrypted by exchange key</param> public void RestoreSecurityDomain(string hsmName, SecurityDomainRestoreData securityDomainData) { string securityDomain = JsonConvert.SerializeObject(new SecurityDomainWrapper { value = JsonConvert.SerializeObject(securityDomainData) }); try { var httpRequest = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new UriBuilder(_uriHelper.CreateManagedHsmUri(hsmName)) { Path = $"/{_securityDomainPathFragment}/upload" }.Uri, Content = new StringContent(securityDomain) }; PrepareRequest(httpRequest); var httpResponseMessage = HttpClient.SendAsync(httpRequest).ConfigureAwait(false).GetAwaiter().GetResult(); var responseBody = httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); if (httpResponseMessage.IsSuccessStatusCode) { if (string.IsNullOrEmpty(responseBody)) { throw new Exception("Got empty response when restoring security domain."); } } else { throw new Exception($"Got {httpResponseMessage.StatusCode}, {responseBody}"); } } catch (Exception ex) { throw new Exception(Resources.RestoreSecurityDomainFailure, ex); } }