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