1 #include <Rinternals.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <openssl/crypto.h>
5 #include <openssl/pem.h>
6 #include "utils.h"
7 #include "compatibility.h"
8 
R_parse_der_pubkey(SEXP input)9 SEXP R_parse_der_pubkey(SEXP input){
10   const unsigned char *ptr = RAW(input);
11   EVP_PKEY *pkey = d2i_PUBKEY(NULL, &ptr, LENGTH(input));
12   bail(!!pkey);
13   unsigned char *buf = NULL;
14   int len = i2d_PUBKEY(pkey, &buf);
15   EVP_PKEY_free(pkey);
16   bail(len);
17   SEXP res = allocVector(RAWSXP, len);
18   memcpy(RAW(res), buf, len);
19   OPENSSL_free(buf);
20   return res;
21 }
22 
R_parse_der_key(SEXP input)23 SEXP R_parse_der_key(SEXP input){
24   BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
25   EVP_PKEY *pkey = d2i_PrivateKey_bio(mem, NULL);
26   BIO_free(mem);
27   bail(!!pkey);
28   unsigned char *buf = NULL;
29   int len = i2d_PrivateKey(pkey, &buf);
30   EVP_PKEY_free(pkey);
31   bail(len);
32   SEXP res = allocVector(RAWSXP, len);
33   memcpy(RAW(res), buf, len);
34   OPENSSL_free(buf);
35   return res;
36 }
37 
R_parse_der_cert(SEXP input)38 SEXP R_parse_der_cert(SEXP input){
39   const unsigned char *ptr = RAW(input);
40   X509 *cert = d2i_X509(NULL, &ptr, LENGTH(input));
41   bail(!!cert);
42   unsigned char *buf = NULL;
43   int len = i2d_X509(cert, &buf);
44   X509_free(cert);
45   bail(len);
46   SEXP res = allocVector(RAWSXP, len);
47   memcpy(RAW(res), buf, len);
48   OPENSSL_free(buf);
49   return res;
50 }
51 
52 /* Convert private to public key */
R_derive_pubkey(SEXP input)53 SEXP R_derive_pubkey(SEXP input){
54   BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
55   EVP_PKEY *pkey = d2i_PrivateKey_bio(mem, NULL);
56   BIO_free(mem);
57   bail(!!pkey);
58   unsigned char *buf = NULL;
59   int len = i2d_PUBKEY(pkey, &buf);
60   EVP_PKEY_free(pkey);
61   bail(len);
62   SEXP res = allocVector(RAWSXP, len);
63   memcpy(RAW(res), buf, len);
64   OPENSSL_free(buf);
65   return res;
66 }
67 
68 /* Convert cert to public key */
R_cert_pubkey(SEXP input)69 SEXP R_cert_pubkey(SEXP input){
70   const unsigned char *ptr = RAW(input);
71   X509 *cert = d2i_X509(NULL, &ptr, LENGTH(input));
72   bail(!!cert);
73   EVP_PKEY *key = X509_get_pubkey(cert);
74   X509_free(cert);
75   bail(!!key);
76   unsigned char *buf = NULL;
77   int len = i2d_PUBKEY(key, &buf);
78   EVP_PKEY_free(key);
79   bail(len);
80   SEXP res = allocVector(RAWSXP, len);
81   memcpy(RAW(res), buf, len);
82   OPENSSL_free(buf);
83   return res;
84 }
85 
R_pubkey_type(SEXP input)86 SEXP R_pubkey_type(SEXP input){
87   BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
88   EVP_PKEY *pkey = d2i_PUBKEY_bio(mem, NULL);
89   BIO_free(mem);
90   if(!pkey)
91     return R_NilValue;
92   const char *keytype;
93   switch(EVP_PKEY_base_id(pkey)){
94   case EVP_PKEY_RSA:
95     keytype = "rsa";
96     break;
97   case EVP_PKEY_DSA:
98     keytype = "dsa";
99     break;
100   case EVP_PKEY_EC:
101     keytype = "ecdsa";
102     break;
103 #ifdef EVP_PKEY_ED25519
104   case EVP_PKEY_X25519:
105     keytype = "x25519";
106     break;
107   case EVP_PKEY_ED25519:
108     keytype = "ed25519";
109     break;
110 #endif
111   default:
112     Rf_error("Unsupported key type: %d", EVP_PKEY_base_id(pkey));
113   }
114   EVP_PKEY_free(pkey);
115   return mkString(keytype);
116 }
117 
ec_bitsize(int nid)118 int ec_bitsize(int nid){
119   switch(nid){
120   case NID_X9_62_prime256v1:
121     return 256;
122   case NID_secp384r1:
123     return 384;
124   case NID_secp521r1:
125     return 521;
126   }
127   return 0;
128 }
129 
R_pubkey_bitsize(SEXP input)130 SEXP R_pubkey_bitsize(SEXP input){
131   BIO *mem = BIO_new_mem_buf(RAW(input), LENGTH(input));
132   EVP_PKEY *pkey = d2i_PUBKEY_bio(mem, NULL);
133   BIO_free(mem);
134   if(!pkey)
135     return R_NilValue;
136   int size = 0;
137   const BIGNUM * val;
138   switch(EVP_PKEY_base_id(pkey)){
139   case EVP_PKEY_RSA:
140     MY_RSA_get0_key(EVP_PKEY_get1_RSA(pkey), &val, NULL, NULL);
141     size = BN_num_bits(val);
142     break;
143   case EVP_PKEY_DSA:
144     MY_DSA_get0_pqg(EVP_PKEY_get1_DSA(pkey), &val, NULL, NULL);
145     size = BN_num_bits(val);
146     break;
147 #ifdef EVP_PKEY_ED25519
148   case EVP_PKEY_ED25519:
149   case EVP_PKEY_X25519:
150     size = 256;
151     break;
152 #endif
153 #ifndef OPENSSL_NO_EC
154   case EVP_PKEY_EC:
155     size = ec_bitsize(EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get1_EC_KEY(pkey))));
156     break;
157 #endif //OPENSSL_NO_EC
158   default:
159     Rf_error("Unsupported key type: %d", EVP_PKEY_base_id(pkey));
160   }
161   EVP_PKEY_free(pkey);
162   return ScalarInteger(size);
163 }
164