| 
					
				 | 
			
			
				@@ -138,12 +138,24 @@ bigfraction_t* cf_next(cf_t *f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   exit(EXIT_FAILURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void BN_int2bn(BIGNUM** a, short int i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!*a) *a = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* trolololololol. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BN_one(*a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (*a)->d[0] = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * \brief Square Root for bignums. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int BN_sqrtmod(BIGNUM* dv, BIGNUM* rem, BIGNUM* a, BN_CTX* ctx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  char *abn2dec, *bbn2dec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  char *abn2dec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int g[100]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  long al, bl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  long al; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   long x = 0, r = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int i, j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int d; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -174,8 +186,6 @@ int BN_sqrtmod(BIGNUM* dv, BIGNUM* rem, BIGNUM* a, BN_CTX* ctx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   BN_dec2bn(&rem, abn2dec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   sprintf(abn2dec, "%ld", x); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   BN_dec2bn(&dv, abn2dec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   OPENSSL_free(abn2dec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return BN_is_zero(rem); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -196,42 +206,82 @@ int wiener_question_test(X509* cert) { return 1; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int wiener_question_ask(X509* cert) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   RSA *rsa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* key data */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   BIGNUM *n, *e, *d, *phi; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  BIGNUM *t, *tmp, *rem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BIGNUM *p, *q; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* continued fractions coefficient, and mod */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cf_t* cf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   bigfraction_t *it; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   size_t  i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BIGNUM *t, *tmp, *rem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* equation coefficients */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BIGNUM *b2, *delta; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BN_CTX *ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rsa = X509_get_pubkey(cert)->pkey.rsa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   phi = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tmp = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   rem = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  rsa = X509_get_pubkey(cert)->pkey.rsa; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   n = rsa->n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   e = rsa->e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cf = cf_init(NULL, n, e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  b2 = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  delta = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * generate the continued fractions approximating e/N 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cf = cf_init(NULL, e, n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ctx = cf->ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (i=0, it = cf_next(cf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       // XXX. how many keys shall I test? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        i!=100 && it; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        i++, it = cf_next(cf)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     t = it->h; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     d = it->k; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Recovering φ(N) = (ed - 1) / t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * TEST1: obviously the couple {t, d} is correct → (ed-1) | t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     BN_mul(phi, e, d, cf->ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    BN_sub(tmp, phi, BN_value_one()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_usub(tmp, phi, BN_value_one()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     BN_div(phi, rem, tmp, t, cf->ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* test 1: there shall be no rem */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (!BN_is_zero(rem)) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    printf("Found? "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    BN_print_fp(stdout, e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    printf(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    BN_print_fp(stdout, d); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    printf(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    BN_print_fp(stdout, phi); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // XXX. check, is it possible to fall here, assuming N, e are valid? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (BN_is_odd(phi) && BN_cmp(n, phi) > 0)   continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Recovering p, q 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Solving the equation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  x² + [N-φ(N)+1]x + N = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * which, after a few passages, boils down to: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  x² + (p+q)x + (pq) = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * TEST2: φ(N) is correct → the two roots of x are integers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_usub(b2, n, phi); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_uadd(b2, b2, BN_value_one()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_rshift(b2, b2, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (BN_is_zero(b2)) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* delta */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_sqr(tmp, b2, ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_usub(delta, tmp, n); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!BN_sqrtmod(tmp, rem, delta, ctx)) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* key found :) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    p = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    q = BN_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_usub(p, b2, tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    BN_uadd(q, b2, tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //printf("Primes: %s %s", BN_bn2dec(p), BN_bn2dec(q)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cf_free(cf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BN_free(rem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BN_free(tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BN_free(b2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BN_free(delta); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  BN_free(phi); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |