Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passphrase can be truncated #115

Open
patrickhartling opened this issue Sep 12, 2014 · 3 comments
Open

Passphrase can be truncated #115

patrickhartling opened this issue Sep 12, 2014 · 3 comments

Comments

@patrickhartling
Copy link
Contributor

In the current handling of the passphrase for SQLCipher, the passphrase type has to be an instance of NSString—or at least something that responds to the message ‑UTF8String. A problem can arise if the passphrase is generated randomly using a function such as SecRandomCopyBytes(). The byte 0 is as likely to occur as any other, but when strlen(3) sees '\0', it concludes that the end of the string has been reached. In the worst case, '\0' is the first character in the random data interpreted as a C string, and the supplied passphrase is effectively ignored as zero-length input.

It would be more robust to use NSData as the type for the passphrase. Since sqlite3_key() expects to be given an array of bytes (not necessarily a char *) of a specified length, NSData is a much better fit for the expectations of SQLCipher than a string. I could submit a pull request to switch over to NSData, but it would break all existing uses of Encrypted Core Data without some backwards compatibility code. At this point, I feel that it might be better to discuss this issue rather than to jump to a conclusion about how to solve it.

@gavin-black
Copy link
Member

Hi @patrickhartling,

Good catch, and definitely would like to get it updated to use NSData. It might be naive, but would it be possible to just check if the byte sequence is a valid UTF8String, and if not use NSData. That would maintain backwards compatibility, but still allow raw bytes.

Playing around, the following code seems to accomplish this:

    // Raw random data
    uint8_t rawData[100];
    SecRandomCopyBytes(kSecRandomDefault, 100, rawData);
    printf("%llu\n", *(uint64_t *)rawData);

    NSData* randomData = [[NSData alloc] initWithBytes:rawData length:100];
    //randomData = [@"validUTFString" dataUsingEncoding:NSUTF8StringEncoding];

    NSString *dataStr;
    dataStr = [[NSString alloc] initWithData:randomData encoding:NSUTF8StringEncoding];
    if (!dataStr ) {
        NSLog(@"Not a UTF8 string %@", randomData);
    } else {
        NSLog(@"UTF8 String is %@", dataStr);
    }

I'm sure there are edge cases I'm not considering, but it would give you a way to figure out if the password could possibly be used in an older version.

@tomasz-czyzak
Copy link
Contributor

and crash if truncation is done on first character

@przemyslaw-szurmak
Copy link

przemyslaw-szurmak commented May 23, 2017

@gavin-black Hi,

any updates on this idea ? Because, together with @tomasz-czyzak-mobica we've noticed that this issue might cause some serious bugs if first string character is null-termination - then strlen treats it as 0-length key thus store opening fails.

Please take a look at related topic #269

DanielBroad added a commit that referenced this issue May 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants