mirror of https://github.com/OpenVPN/openvpn-gui
				
				
				
			passphrase.c: on failure to decrypt private key, retry with legacy provider
- Support legacy algorithms while decrypting keys by loading legacy provider unless default pros has fips enabled. - Use the recommended PKCS8 format and AES-256-CBC cipher when encrypting PEM keys. For PKCS12, OpenSSL's default is used which is PBKDF2 with AES-256-CBC in OpenSSL 3.0 Signed-off-by: Selva Nair <selva.nair@gmail.com>pull/483/head
							parent
							
								
									24b9d06957
								
							
						
					
					
						commit
						9356ccb806
					
				
							
								
								
									
										106
									
								
								passphrase.c
								
								
								
								
							
							
						
						
									
										106
									
								
								passphrase.c
								
								
								
								
							|  | @ -47,6 +47,11 @@ | |||
| #include "localization.h" | ||||
| #include "misc.h" | ||||
| 
 | ||||
| #if OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
| #include <openssl/provider.h> | ||||
| static OSSL_PROVIDER *legacy = NULL; | ||||
| #endif | ||||
| 
 | ||||
| extern options_t o; | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -82,6 +87,40 @@ const int KEYFILE_FORMAT_PKCS12 = 1; | |||
| const int KEYFILE_FORMAT_PEM = 2; | ||||
| const int MIN_PASSWORD_LEN = 8; | ||||
| 
 | ||||
| /* Load legacy provider if not fips and not already
 | ||||
|  * loaded and return true if explicitly loaded. | ||||
|  */ | ||||
| bool | ||||
| load_legacy(void) | ||||
| { | ||||
| #if OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
|     if (EVP_default_properties_is_fips_enabled(NULL) | ||||
|         || OSSL_PROVIDER_available(NULL, "legacy")) | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     legacy = OSSL_PROVIDER_load(NULL, "legacy"); | ||||
|     if (!legacy) | ||||
|     { | ||||
|         MsgToEventLog(EVENTLOG_ERROR_TYPE, L"failed to load legacy provider "); | ||||
|     } | ||||
|     return (legacy != NULL); | ||||
| #else | ||||
|     return false; | ||||
| #endif /* OPENSSL 3.0+ */ | ||||
| } | ||||
| 
 | ||||
| void | ||||
| unload_legacy(void) | ||||
| { | ||||
| #if OPENSSL_VERSION_NUMBER >= 0x30000000L | ||||
|     if (legacy) | ||||
|     { | ||||
|         OSSL_PROVIDER_unload(legacy); | ||||
|     } | ||||
| #endif /* OPENSSL 3.0+ */ | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Return TRUE if new passwords match | ||||
|  | @ -186,16 +225,33 @@ ChangePasswordPEM(HWND hwndDlg) | |||
|       return(0); | ||||
|     } | ||||
| 
 | ||||
|   /* Import old key */ | ||||
|   if (! (privkey = PEM_read_PrivateKey (fp, NULL, NULL, oldpsw))) | ||||
|     /* Import old key */ | ||||
|     for (int trial = 0; trial < 2; trial++) | ||||
|     { | ||||
|       /* wrong password */ | ||||
|       ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT); | ||||
|       fclose(fp); | ||||
|       return(-1); | ||||
|     } | ||||
|         if ((privkey = PEM_read_PrivateKey (fp, NULL, NULL, oldpsw))) | ||||
|         { | ||||
|             break; /* key imported */ | ||||
|         } | ||||
|         /* try again with legacy provider loaded */ | ||||
|         else if (trial == 0 && load_legacy()) | ||||
|         { | ||||
|             PrintDebug(L"Private key decrypt failed. Try again with legacy provider"); | ||||
|             rewind(fp); | ||||
|             continue; | ||||
|         } | ||||
|         if (ERR_get_error() == EVP_R_UNSUPPORTED_ALGORITHM) | ||||
|         { | ||||
|             MsgToEventLog(EVENTLOG_ERROR_TYPE, L"OpenSSL error: unsupported algorithm"); | ||||
|         } | ||||
|         unload_legacy(); | ||||
| 
 | ||||
|   fclose(fp); | ||||
|         /* wrong password? */ | ||||
|         ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT); | ||||
|         fclose(fp); | ||||
|         return(-1); | ||||
|     } | ||||
|     unload_legacy(); | ||||
|     fclose(fp); | ||||
| 
 | ||||
|   /* Open keyfile for writing */ | ||||
|   if (! (fp = _tfopen (keyfile, _T("w")))) | ||||
|  | @ -224,9 +280,9 @@ ChangePasswordPEM(HWND hwndDlg) | |||
|   else | ||||
|     { | ||||
|       /* Use passphrase */ | ||||
|       if ( !(PEM_write_PrivateKey(fp, privkey, \ | ||||
|                                   EVP_des_ede3_cbc(),  /* Use 3DES encryption */ | ||||
|                                   (UCHAR*) newpsw, (int) strlen(newpsw), 0, NULL))) | ||||
|       if ( !(PEM_write_PKCS8PrivateKey(fp, privkey, | ||||
|                                   EVP_aes_256_cbc(), | ||||
|                                   newpsw, (int) strlen(newpsw), 0, NULL))) | ||||
|         { | ||||
|           /* can't write new key */ | ||||
|           ShowLocalizedMsg(IDS_ERR_WRITE_NEW_KEY, keyfile); | ||||
|  | @ -296,14 +352,30 @@ ChangePasswordPKCS12(HWND hwndDlg) | |||
|       return(0); | ||||
|     } | ||||
| 
 | ||||
|   /* Parse the PKCS #12 file */ | ||||
|   if (!PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca)) | ||||
|     /* Parse the PKCS #12 file */ | ||||
|     for (int trial = 0; trial < 2; trial++) | ||||
|     { | ||||
|       /* old password incorrect */ | ||||
|       ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT); | ||||
|       PKCS12_free(p12); | ||||
|       return(-1); | ||||
|         if (PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca)) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
|         /* try again with legacy provider loaded */ | ||||
|         else if (trial == 0 && load_legacy()) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|         if (ERR_get_error() == EVP_R_UNSUPPORTED_ALGORITHM) | ||||
|         { | ||||
|             MsgToEventLog(EVENTLOG_ERROR_TYPE, L"OpenSSL error: unsupported algorithm"); | ||||
|         } | ||||
|         unload_legacy(); | ||||
| 
 | ||||
|         /* old password incorrect ? */ | ||||
|         ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT); | ||||
|         PKCS12_free(p12); | ||||
|         return(-1); | ||||
|     } | ||||
|     unload_legacy(); | ||||
| 
 | ||||
|   /* Free old PKCS12 object */ | ||||
|   PKCS12_free(p12); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Selva Nair
						Selva Nair