Skip to content

Replace third party header with OASIS official #66

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

Closed
wants to merge 14 commits into from

Conversation

vkkoskie
Copy link
Contributor

Not quite ready for merge. Read each commit message, which explain some potential areas of concern.

I was unable to update bindings for two targets, so this will fail normal CI tests until that's corrected in some way.

closes #65
moots #64

@vkkoskie
Copy link
Contributor Author

Hmm. CI is seg faulting. My guess is the struct packing, but I won't have time to dig into this again for a while. One of the things I was scratching my head about while making these changes was how anything was working before with unpacked structs. Updating the packing is technically independent of the header swap, but still needed.

@mike-boquard
Copy link
Collaborator

mike-boquard commented Nov 16, 2021

What prompted the change in 8226a25? I'm of the opinion we shouldn't touch the headers unless we have to.

EDIT: If we do decide to change the headers because of bindgen, I believe that a script should be provided that shows how (and why) these changes are made.

Comment on lines 267 to 269
// Restore prior pack setting
#pragma pack(pop)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe explicit struct packing is really only needed for MSC based compilers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure what you mean by this exactly. Are you saying that elsewhere, the default packing is what PKCS11 requires?

If so, then I'm not sure what to make of the bindings I generated. I was curious enough about that detail that I split the bindings updates into before- and after-pack commits to create a nice diff.

@vkkoskie
Copy link
Contributor Author

What prompted the change in 8226a25? I'm of the opinion we shouldn't touch the headers unless we have to.

This was a byproduct of me misinterpreting this comment or maybe just trusting it too much. Much later, when I started messing with the build script, I realized that preprocessor definitions were being excluded because they needed to be explicitly added with allowlist_var.

I didn't revert at that time because I liked the fact that const definitions caused the types to be propagated up into the bindings. But Rust's type aliasing really does just make these synonyms with whatever's backing CK_ULONG and is really only functioning as a documentation method.

It's fairly weak justification to keep them if having the headers be as pure as possible is a goal. That purity wasn't present in the headers I was replacing, though, so I figured I had a bit more freedom to customize.

EDIT: If we do decide to change the headers because of bindgen, I believe that a script should be provided that shows how (and why) these changes are made.

Yeah, agreed this wasn't my best commit message.

@vkkoskie
Copy link
Contributor Author

Okay, I basically started over, cherry-picking the first draft of commits as needed. The branch now touches the headers as little as possible. There are still some modifications to look at though.

And again, I've disabled Darwin and Windows support because I don't have those toolchains available, and they'd just fail. Not exactly sure what the best way forward is there.

The only struct packing left is the MSC stuff you provided, which doesn't get used on my end. I'm still very confused about when this does and doesn't matter. But I'm comfortable not making it a condition of merging because it wasn't present before and so you're no worse off keeping it as is.

@vkkoskie
Copy link
Contributor Author

EDIT: If we do decide to change the headers because of bindgen, I believe that a script should be provided that shows how (and why) these changes are made.

I've now managed to get all but one of the changes needed from the base header implemented in build.rs at generation time. The last one is a disagreement that can crop up between bindgen's preprocessor and compiler passes that I don't see a clean way around. I think it's minor enough to leave as is though.

@ionut-arm
Copy link
Member

ionut-arm commented Nov 21, 2021

Hey,

Finally got some time to look through this.

  1. could you please expand the comment in eff8917 to link to the place where those header files were taken from?
  2. @mjb3279 - after this is merged could you regenerate the Windows bindings? I'll try to do the same for Mac OS
  3. One of the things I was scratching my head about while making these changes was how anything was working before with unpacked structs. - what do you mean? I thought bindgen takes care of this (or maybe I'm thinking of the wrong thing)

@vkkoskie
Copy link
Contributor Author

Hey,

Finally got some time to look through this.

1. could you please expand the comment in [eff8917](https://github.com/parallaxsecond/rust-cryptoki/commit/eff891738d3c669030ec7d8a09a01bea1d2d0191) to link to the place where those header files were taken from?

Sure. Just update the commit message or drop a README in the oasis-headers directory? Or both? Also, is the licensing information at the top of the headers sufficient? I'm trying to parse their legal pages but am having trouble finding anything directed at derivative products instead of OASIS official notices.

2. @mjb3279 - after this is merged could you regenerate the Windows bindings? I'll try to do the same for Mac OS

If you place these in any commit I have access to, I'll be able to cherry-pick them into this PR pre-merge.

3. `One of the things I was scratching my head about while making these changes was how anything was working before with unpacked structs.` - what do you mean? I thought `bindgen` takes care of this (or maybe I'm thinking of the wrong thing)

It's the difference between #[repr(C)] and #[repr(C,packed)] in the generated bindings. It's been rebased out of the current PR, but if you look at 60a3a3f you can see the difference between the two. In particular, struct sizes shrink in many places. It also makes the tests seg fault. But the packed representation is an explicit feature of the standard because that's the only one with any guarantee of ABI consistency.

There's definitely more investigating to do, and I haven't looked at it much myself. But it can be treated separately from this PR, and should probably have its own tracking issue.

@ionut-arm
Copy link
Member

Sorry for the very sluggish replies.

Sure. Just update the commit message or drop a README in the oasis-headers directory? Or both? Also, is the licensing information at the top of the headers sufficient? I'm trying to parse their legal pages but am having trouble finding anything directed at derivative products instead of OASIS official notices.

Just the commit message should be fine. As for the license... hmm, good point, I'll have to find out.

If you place these in any commit I have access to, I'll be able to cherry-pick them into this PR pre-merge.

Should be ok to just do it in separate PRs, no need to complicate this one.

It's the difference between #[repr(C)] and #[repr(C,packed)] in the generated bindings. It's been rebased out of the current PR, but if you look at 60a3a3f you can see the difference between the two. In particular, struct sizes shrink in many places. It also makes the tests seg fault. But the packed representation is an explicit feature of the standard because that's the only one with any guarantee of ABI consistency.

There's definitely more investigating to do, and I haven't looked at it much myself. But it can be treated separately from this PR, and should probably have its own tracking issue.

Ah, that makes sense. Ok, a new issue it is - should I create it? I think you have the details lined up more finely.

I'll have another read through the PR, though I need to figure out if there are any restrictions/barriers for us to include those header files. Maybe we can just pull them at build time if need be?

@ionut-arm
Copy link
Member

ionut-arm commented Dec 3, 2021

Hi @vkkoskie !

I'm not sure if you managed to find more information on the issue regarding Oasis licenses.

I've queried internally and it seems the headers are indeed under Oasis IPR, however the IPR is incompatible with our Apache-2.0 license (as it requires limiting distribution to members of Oasis only), so the PR can't be merged in its current form. However, I still don't know if pulling them in at build time to generate the FFI code is any better. Do you happen to have any more insight into that?

The Oasis headers appear to be more of a spec in code form. At the same time, I don't know which other headers we should be using for our goals... It appears SoftHSM essentially did the inverse of this PR a few years ago, replacing the Oasis ones with the ones we currently use, from p11-kit, PR here (thank you @paulhowardarm for pointing that out)

@vkkoskie
Copy link
Contributor Author

vkkoskie commented Dec 3, 2021

Interesting. I followed a few links down from yours to this page that seems to at least acknowledge that someone might actually want to use OASIS work product instead of just contribute to it.

That led me to search github to see of a repo existed, which does exist. (What's currently committed came from from OASIS's own domain.) The license there is boilerplate (as noted in its commit message) and links to other places in the OASIS legal docs that are also beyond the limits of my legal knowledge. My best guess is that the headers can be used under BSD-3-Clause, but I've filed an issue on that repo to get clarification.

@ionut-arm
Copy link
Member

ionut-arm commented Dec 3, 2021

Thanks for following that up, it sounds promising! I'll subscribe to the issue you raised, let's see what they reply :)

@vkkoskie vkkoskie force-pushed the header-rework branch 2 times, most recently from 21458b9 to ffd636c Compare December 4, 2021 17:59
@mike-boquard
Copy link
Collaborator

Hey everyone. Sorry for disappearing as of late. I normally get to work on this repo when there is a lull in work, however lately I've been absolutely swamped with work and family stuff. Hopefully early next year things will calm down and I can get back to contributing.

@ionut-arm
Copy link
Member

Hey everyone. Sorry for disappearing as of late. I normally get to work on this repo when there is a lull in work, however lately I've been absolutely swamped with work and family stuff. Hopefully early next year things will calm down and I can get back to contributing.

I'm in pretty much the same situation, hope we're not slowing @vkkoskie down too much 😅

Header content provided by oasis-open.org, cloned from
https://github.com/oasis-tcs/pkcs11.git and using content under the
`2-40-errata-1` tag.

Signed-off-by: Keith Koskie <[email protected]>
This is a convenience for the sake of upcoming commits.
It allows the cfg check macro to be defined on the module
and not have to add it to every single item.

It's unformatted to so whitespace doesn't mask the content
diff. The next commit applies rust fmt.

Signed-off-by: Keith Koskie <[email protected]>
Signed-off-by: Keith Koskie <[email protected]>
Multiple things happening here:
* Add allowlist_var() to make bindgen include constants, which are
  excluded by default.
* Set integer types for generated constants. Bindgen will parse types
  in C declarations, but ignores any kind of type information (e.g.,
  a "UL" suffix) on integer literals defined as macros. This sets the
  two bool constants to unsigned bytes, and assumes everything else
  will be an unsigned long.
* Filter macro names that don't need bindings (e.g., include guards),
* Filter out deprecations. In most cases these have been replaced with
  an identical type under a different name, so no functionality is being
  omitted.
* Filter out some additional alternate spellings that aren't explicitly
  deprecated. These get used in Rust enums, where having one value with
  two descriminant names is disallowed, and breaks pattern matching.

Signed-off-by: Keith Koskie <[email protected]>
A weird edge case.  Based on observed behavior, bindgen
parses preprocessor constants as either i64 (implied by
the int_macro callback) or to the width of the type
returned by that callback (ulong) *on the generating
platform*.  This may not agree with the specified target,
though.

Regardless, from my 64-bit platform, this ~0 gets converted
to u64::MAX as a decimal literal. Then bindgen creates a
declaration with a type equivalent to the target's ulong.
If that type is only 32-bits wide, the compiler reports
the overflowing literal as an error.

To correct this, change the preprocessor definition to its
C declaration equivalent because bindgen properly uses the
target's types for both parsing and generation.

Signed-off-by: Keith Koskie <[email protected]>
Not sure if these are indespensible. These mechanisms appear
in v3.0 but aren't defined in v2.40 spec or headers.

It seems easier to to me to add 3.0 *after* a relatively clean
2.40 implementation is in place providing a stable(-ish) surface
to layer onto, but there may be more context to why this was
already implemented that makes a different path more appropriate.

Signed-off-by: Keith Koskie <[email protected]>
Reverts parallaxsecond#13
See also: parallaxsecond#12

It appears that bindgen no longer generates the code
that this suppression was written for. The resulting
bindings are identical.

Signed-off-by: Keith Koskie <[email protected]>
@jhagborgftx
Copy link
Contributor

It seems that structure packing should be limited to Windows. This is a known inaccuracy of the spec, and there is a proposal to change this in v3.2. This was accepted without objection according to these meeting minutes.

Even in older versions of the spec, it seems nobody was actually packing structures on Unix. So following the spec literally will cause ABI incompatibility with every existing PKCS#11 implementation.

@wiktor-k
Copy link
Collaborator

wiktor-k commented Jan 4, 2023

I propose we close this PR. It doesn't see much progress lately and there are parallel efforts to update the PKCS version in other PRs/issues. Also closing doesn't hurt since the code is still here and in case something happens we can re-open.

Thoughts?

@ionut-arm
Copy link
Member

I propose we close this PR. It doesn't see much progress lately and there are parallel efforts to update the PKCS version in other PRs/issues. Also closing doesn't hurt since the code is still here and in case something happens we can re-open.

Thoughts?

Agree, it's gone somewhat stale, I'd be happy to close. If we need to revisit the topic, we can re-open or link to this one from a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Current pkcs11.h is not up-to-date
5 participants