Skip to content

Enlarge _oid2txt buffer to handle larger OIDs #3612

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

Merged
merged 1 commit into from
May 29, 2017

Conversation

frasertweedale
Copy link
Contributor

The OpenSSL manual recommends a buffer size of 80 for OBJ_oid2txt:
https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values.
But OIDs longer than this occur in real life (e.g. Active Directory
makes some very long OIDs). Use a more conservative buffer size of
256 to prevent crashes if the length of the stringified-OID exceeds
80 characters.

@mention-bot
Copy link

@frasertweedale, thanks for your PR! By analyzing the history of the files in this pull request, we identified @alex, @reaperhulk and @intgr to be potential reviewers.

@alex alex added the x509 label May 26, 2017
@alex alex added this to the Nineteenth Release milestone May 26, 2017
@alex
Copy link
Member

alex commented May 26, 2017

It looks like you forgot to git add bigoid.pem.

@reaperhulk
Copy link
Member

bigoid.pem will also need to be documented in the test-vectors.rst when it's added 😄

@frasertweedale frasertweedale force-pushed the fix/long-oid-parse-failure branch from 5101e7a to f3f77f9 Compare May 26, 2017 02:57
@frasertweedale
Copy link
Contributor Author

@reaperhulk whups, thanks! test-vectors.rst update imminent.

@frasertweedale frasertweedale force-pushed the fix/long-oid-parse-failure branch from f3f77f9 to 2f3c2da Compare May 26, 2017 03:00
@alex
Copy link
Member

alex commented May 26, 2017

@stevepeak we appear to have hit a bug of some sort - the Changes page for this diff isn't showing the actual source, just a blank space:

screen shot 2017-05-25 at 11 37 23 pm

@stevepeak
Copy link

Cool :) Nice edge case. I'll review 👍

@alex
Copy link
Member

alex commented May 26, 2017

@stevepeak thanks, we appreciate it!

@frasertweedale
Copy link
Contributor Author

Don't merge this; better fix coming.

The OpenSSL manual recommends a buffer size of 80 for OBJ_oid2txt:
https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values.
But OIDs longer than this occur in real life (e.g. Active Directory
makes some very long OIDs).  If the length of the stringified OID
exceeds the buffer size, allocate a new buffer that is big enough to
hold the stringified OID, and re-do the conversion into the new
buffer.
@frasertweedale frasertweedale force-pushed the fix/long-oid-parse-failure branch from 2f3c2da to effeb60 Compare May 29, 2017 02:16
@alex
Copy link
Member

alex commented May 29, 2017

Is it possible to call OBJ_obj2txt with a NULL buffer to get the size?

@frasertweedale
Copy link
Contributor Author

frasertweedale commented May 29, 2017 via email

@alex
Copy link
Member

alex commented May 29, 2017

I feel like the correct answer is "let's benchmark!", but that seems like way too much work to ask you to do for what should be simple. @reaperhulk or I will review as-is I think.

res = backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
if res > buf_len - 1: # account for terminating null byte
buf_len = res + 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix is not sufficient. OBJ_obj2txt(buf, buf_len, obj, 1) does not return the actual required buffer size. You have to call the function with NULL buffer to make it calculate the correct size: OBJ_obj2txt(NULL, 0, obj, 1).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This is not accurate, a later tiran comment shows that it does return required buffer size)

buf_len = 80
buf = backend._ffi.new("char[]", buf_len)

# 'res' is the number of bytes that *would* be written if the
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is maybe not correct. More testing needed. Don't merge.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Confirmed that this is correct in a later comment by tiran)

@tiran
Copy link
Contributor

tiran commented May 29, 2017

Your code was correct. It looks like I screwed up while I was adopting your patch for CPython. The ssl module calls OBJ_obj2txt() in two different functions. The second time it calls the function with no_name=1. I think I mistakenly copied code with no_name=0.

test case

#include <stdio.h>
#include "openssl/x509.h"

int main(int argc, char **argv) {
    char buf[5];
    char largebuf[256];
    int buflen, i;
    ASN1_OBJECT *obj;
    obj = OBJ_nid2obj(NID_server_auth);

    for (i=0; i < 2; i++) {
        buflen = OBJ_obj2txt(NULL, 0, obj, i);
        fprintf(stdout, "NULL buffer\t\tno_name: %d\tbuflen: %d\n", i, buflen);
        buflen = OBJ_obj2txt(buf, sizeof(buf), obj, i);
        fprintf(stdout, "small buffer %d\t\tno_name: %d\tbuflen: %d\n",
                sizeof(buf), i, buflen);
        buflen = OBJ_obj2txt(largebuf, sizeof(largebuf), obj, i);
        fprintf(stdout, "large buffer %d\tno_name: %d\tbuflen: %d\n",
                sizeof(largebuf), i, buflen);
        fprintf(stdout, "%s\n", largebuf);
    }
}

output

$ gcc -lcrypto obj2txt.c -o obj2txt && ./obj2txt 
NULL buffer             no_name: 0      buflen: 29
small buffer 5          no_name: 0      buflen: 29
large buffer 256        no_name: 0      buflen: 29
TLS Web Server Authentication
NULL buffer             no_name: 1      buflen: 17
small buffer 5          no_name: 1      buflen: 17
large buffer 256        no_name: 1      buflen: 17
1.3.6.1.5.5.7.3.1

@frasertweedale
Copy link
Contributor Author

@tiran thanks for the update 👍

Copy link
Member

@reaperhulk reaperhulk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this approach is fine by me

@reaperhulk
Copy link
Member

@alex if you have no objections I'll merge this shortly so it can be in 1.9.

@alex
Copy link
Member

alex commented May 29, 2017 via email

@reaperhulk reaperhulk merged commit d607dd7 into pyca:master May 29, 2017
@frasertweedale frasertweedale deleted the fix/long-oid-parse-failure branch May 29, 2017 23:56
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

Successfully merging this pull request may close these issues.

6 participants