1 #include <Rinternals.h>
2 #include <string.h>
3 #include <openssl/crypto.h>
4 #include <openssl/evp.h>
5 #include <openssl/rsa.h>
6 #include <openssl/dsa.h>
7 #include "utils.h"
8
9 #ifndef OPENSSL_NO_EC
10 #include <openssl/ec.h>
11 #endif
12
13 #ifdef EVP_PKEY_ED25519
14 #define HAS_ECX
15 #endif
16
R_keygen_rsa(SEXP bits)17 SEXP R_keygen_rsa(SEXP bits){
18 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
19 bail(!!ctx);
20 bail(EVP_PKEY_keygen_init(ctx) > 0);
21 bail(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, asInteger(bits)) > 0);
22 EVP_PKEY *pkey = NULL;
23 bail(EVP_PKEY_keygen(ctx, &pkey) > 0);
24 unsigned char *buf = NULL;
25 int len = i2d_PrivateKey(pkey, &buf);
26 bail(len);
27 EVP_PKEY_free(pkey);
28 EVP_PKEY_CTX_free(ctx);
29 SEXP res = allocVector(RAWSXP, len);
30 memcpy(RAW(res), buf, len);
31 OPENSSL_free(buf);
32 return res;
33 }
34
R_keygen_dsa(SEXP bits)35 SEXP R_keygen_dsa(SEXP bits){
36 DSA *dsa = DSA_new();
37 bail(DSA_generate_parameters_ex(dsa, asInteger(bits), NULL, 0, NULL, NULL, NULL));
38 bail(DSA_generate_key(dsa));
39 unsigned char *buf = NULL;
40 int len = i2d_DSAPrivateKey(dsa, &buf);
41 bail(len);
42 DSA_free(dsa);
43 SEXP res = allocVector(RAWSXP, len);
44 memcpy(RAW(res), buf, len);
45 OPENSSL_free(buf);
46 return res;
47 }
48
R_keygen_ecdsa(SEXP curve)49 SEXP R_keygen_ecdsa(SEXP curve){
50 #ifndef OPENSSL_NO_EC
51 int nid = my_nist2nid(CHAR(STRING_ELT(curve, 0)));
52 EC_KEY *eckey = EC_KEY_new_by_curve_name(nid);
53 bail(!!eckey);
54 bail(EC_KEY_generate_key(eckey) > 0);
55 EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
56 EVP_PKEY *pkey = EVP_PKEY_new();
57 bail(!!pkey);
58 bail(EVP_PKEY_assign_EC_KEY(pkey, eckey) > 0);
59 unsigned char *buf = NULL;
60 int len = i2d_PrivateKey(pkey, &buf);
61 bail(len > 0);
62 EVP_PKEY_free(pkey);
63 SEXP res = allocVector(RAWSXP, len);
64 memcpy(RAW(res), buf, len);
65 OPENSSL_free(buf);
66 return res;
67 #else //OPENSSL_NO_EC
68 Rf_error("OpenSSL has been configured without EC support");
69 #endif //OPENSSL_NO_EC
70 }
71
R_keygen_x25519()72 SEXP R_keygen_x25519(){
73 #ifdef HAS_ECX
74 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
75 bail(!!ctx);
76 bail(EVP_PKEY_keygen_init(ctx) > 0);
77 EVP_PKEY *pkey = NULL;
78 bail(EVP_PKEY_keygen(ctx, &pkey) > 0);
79 unsigned char *buf = NULL;
80 int len = i2d_PrivateKey(pkey, &buf);
81 bail(len);
82 EVP_PKEY_free(pkey);
83 EVP_PKEY_CTX_free(ctx);
84 SEXP res = allocVector(RAWSXP, len);
85 memcpy(RAW(res), buf, len);
86 OPENSSL_free(buf);
87 return res;
88 #else
89 Rf_error("Curve25519 requires OpenSSL 1.1.1 or newer.");
90 #endif
91 }
92
R_keygen_ed25519()93 SEXP R_keygen_ed25519(){
94 #ifdef HAS_ECX
95 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
96 bail(!!ctx);
97 bail(EVP_PKEY_keygen_init(ctx) > 0);
98 EVP_PKEY *pkey = NULL;
99 bail(EVP_PKEY_keygen(ctx, &pkey) > 0);
100 unsigned char *buf = NULL;
101 int len = i2d_PrivateKey(pkey, &buf);
102 bail(len);
103 EVP_PKEY_free(pkey);
104 EVP_PKEY_CTX_free(ctx);
105 SEXP res = allocVector(RAWSXP, len);
106 memcpy(RAW(res), buf, len);
107 OPENSSL_free(buf);
108 return res;
109 #else
110 Rf_error("Curve25519 requires OpenSSL 1.1.1 or newer.");
111 #endif
112 }
113