summaryrefslogtreecommitdiff
path: root/libs/libssh2/src/pem.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libssh2/src/pem.c')
-rw-r--r--libs/libssh2/src/pem.c112
1 files changed, 66 insertions, 46 deletions
diff --git a/libs/libssh2/src/pem.c b/libs/libssh2/src/pem.c
index c658896809..c9ab774690 100644
--- a/libs/libssh2/src/pem.c
+++ b/libs/libssh2/src/pem.c
@@ -126,8 +126,7 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
- }
- while(strcmp(line, headerbegin) != 0);
+ } while(strcmp(line, headerbegin) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
@@ -263,13 +262,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
goto out;
}
- while(len_decrypted <= (int)*datalen - blocksize) {
- if(method->crypt(session, *data + len_decrypted, blocksize,
- &abstract,
- len_decrypted == 0 ? FIRST_BLOCK :
- ((len_decrypted == (int)*datalen - blocksize) ?
- LAST_BLOCK : MIDDLE_BLOCK)
- )) {
+ if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
+ if(method->crypt(session, 0, *data, *datalen, &abstract, 0)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
@@ -277,8 +271,25 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
LIBSSH2_FREE(session, *data);
goto out;
}
+ }
+ else {
+ while(len_decrypted <= (int)*datalen - blocksize) {
+ if(method->crypt(session, 0, *data + len_decrypted, blocksize,
+ &abstract,
+ len_decrypted == 0 ? FIRST_BLOCK :
+ ((len_decrypted == (int)*datalen - blocksize) ?
+ LAST_BLOCK : MIDDLE_BLOCK)
+ )) {
+ ret = LIBSSH2_ERROR_DECRYPT;
+ _libssh2_explicit_zero((char *)secret, sizeof(secret));
+ method->dtor(session, &abstract);
+ _libssh2_explicit_zero(*data, *datalen);
+ LIBSSH2_FREE(session, *data);
+ goto out;
+ }
- len_decrypted += blocksize;
+ len_decrypted += blocksize;
+ }
}
/* Account for padding */
@@ -323,8 +334,7 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
- }
- while(strcmp(line, headerbegin) != 0);
+ } while(strcmp(line, headerbegin) != 0);
*line = '\0';
@@ -599,46 +609,58 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
goto out;
}
- while((size_t)len_decrypted <= decrypted.len - blocksize) {
- /* We always pass MIDDLE_BLOCK here because OpenSSH Key Files
- * do not use AAD to authenticate the length.
- * Furthermore, the authentication tag is appended after the
- * encrypted key, and the length of the authentication tag is
- * not included in the key length, so we check it after the
- * loop.
- */
- if(method->crypt(session, decrypted.data + len_decrypted,
- blocksize,
+ if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
+ if(method->crypt(session, 0, decrypted.data,
+ decrypted.len,
&abstract,
MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
-
- len_decrypted += blocksize;
}
+ else {
+ while((size_t)len_decrypted <= decrypted.len - blocksize) {
+ /* We always pass MIDDLE_BLOCK here because OpenSSH Key Files
+ * do not use AAD to authenticate the length.
+ * Furthermore, the authentication tag is appended after the
+ * encrypted key, and the length of the authentication tag is
+ * not included in the key length, so we check it after the
+ * loop.
+ */
+ if(method->crypt(session, 0, decrypted.data + len_decrypted,
+ blocksize,
+ &abstract,
+ MIDDLE_BLOCK)) {
+ ret = LIBSSH2_ERROR_DECRYPT;
+ method->dtor(session, &abstract);
+ goto out;
+ }
- /* No padding */
-
- /* for the AES GCM methods, the 16 byte authentication tag is
- * appended to the encrypted key */
- if(strcmp(method->name, "aes256-gcm@openssh.com") == 0 ||
- strcmp(method->name, "aes128-gcm@openssh.com") == 0) {
- if(!_libssh2_check_length(&decoded, 16)) {
- ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
- "GCM auth tag missing");
- method->dtor(session, &abstract);
- goto out;
+ len_decrypted += blocksize;
}
- if(method->crypt(session, decoded.dataptr, 16, &abstract,
- LAST_BLOCK)) {
- ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
- "GCM auth tag invalid");
- method->dtor(session, &abstract);
- goto out;
+
+ /* No padding */
+
+ /* for the AES GCM methods, the 16 byte authentication tag is
+ * appended to the encrypted key */
+ if(strcmp(method->name, "aes256-gcm@openssh.com") == 0 ||
+ strcmp(method->name, "aes128-gcm@openssh.com") == 0) {
+ if(!_libssh2_check_length(&decoded, 16)) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "GCM auth tag missing");
+ method->dtor(session, &abstract);
+ goto out;
+ }
+ if(method->crypt(session, 0, decoded.dataptr, 16, &abstract,
+ LAST_BLOCK)) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
+ "GCM auth tag invalid");
+ method->dtor(session, &abstract);
+ goto out;
+ }
+ decoded.dataptr += 16;
}
- decoded.dataptr += 16;
}
method->dtor(session, &abstract);
@@ -722,8 +744,7 @@ _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
- }
- while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
+ } while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
@@ -803,8 +824,7 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
- }
- while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
+ } while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
*line = '\0';