summaryrefslogtreecommitdiff
path: root/ext/crypto/shared.rs
blob: 0b70db24ea7d3a6276d8280f3c9a4154e7a3f8c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use std::borrow::Cow;

use deno_core::error::custom_error;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::ZeroCopyBuf;
use rsa::pkcs1::FromRsaPrivateKey;
use rsa::pkcs1::ToRsaPublicKey;
use rsa::RsaPrivateKey;
use serde::Deserialize;
use serde::Serialize;

pub const RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.1");
pub const SHA1_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.5");
pub const SHA256_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.11");
pub const SHA384_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.12");
pub const SHA512_RSA_ENCRYPTION_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.13");
pub const RSASSA_PSS_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.10");
pub const ID_SHA1_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.3.14.3.2.26");
pub const ID_SHA256_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.1");
pub const ID_SHA384_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.2");
pub const ID_SHA512_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("2.16.840.1.101.3.4.2.3");
pub const ID_MFG1: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.8");
pub const RSAES_OAEP_OID: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.7");
pub const ID_P_SPECIFIED: rsa::pkcs8::ObjectIdentifier =
  rsa::pkcs8::ObjectIdentifier::new("1.2.840.113549.1.1.9");

#[derive(Serialize, Deserialize, Copy, Clone, PartialEq)]
pub enum ShaHash {
  #[serde(rename = "SHA-1")]
  Sha1,
  #[serde(rename = "SHA-256")]
  Sha256,
  #[serde(rename = "SHA-384")]
  Sha384,
  #[serde(rename = "SHA-512")]
  Sha512,
}

#[derive(Serialize, Deserialize, Copy, Clone, PartialEq)]
pub enum EcNamedCurve {
  #[serde(rename = "P-256")]
  P256,
  #[serde(rename = "P-384")]
  P384,
}

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "lowercase", tag = "type", content = "data")]
pub enum RawKeyData {
  Secret(ZeroCopyBuf),
  Private(ZeroCopyBuf),
  Public(ZeroCopyBuf),
}

impl RawKeyData {
  pub fn as_rsa_public_key(&self) -> Result<Cow<'_, [u8]>, AnyError> {
    match self {
      RawKeyData::Public(data) => Ok(Cow::Borrowed(data)),
      RawKeyData::Private(data) => {
        let private_key = RsaPrivateKey::from_pkcs1_der(data)
          .map_err(|_| type_error("expected valid private key"))?;

        let public_key_doc = private_key
          .to_public_key()
          .to_pkcs1_der()
          .map_err(|_| type_error("expected valid public key"))?;

        Ok(Cow::Owned(public_key_doc.as_der().into()))
      }
      _ => Err(type_error("expected public key")),
    }
  }

  pub fn as_rsa_private_key(&self) -> Result<&[u8], AnyError> {
    match self {
      RawKeyData::Private(data) => Ok(data),
      _ => Err(type_error("expected private key")),
    }
  }
}

pub fn data_error(msg: impl Into<Cow<'static, str>>) -> AnyError {
  custom_error("DOMExceptionDataError", msg)
}

pub fn not_supported_error(msg: impl Into<Cow<'static, str>>) -> AnyError {
  custom_error("DOMExceptionNotSupportedError", msg)
}

pub fn operation_error(msg: impl Into<Cow<'static, str>>) -> AnyError {
  custom_error("DOMExceptionOperationError", msg)
}

pub fn unsupported_format() -> AnyError {
  not_supported_error("unsupported format")
}