I'm using DTLS v1.0 to communicate with a server. I'm having some trouble figuring out exactly what to do to generate the certificate verify message. I've been reading the RFCs (DTLSv1.0 and TLS1.1, which DTLS v1.0 is based on) but they're somewhat non-specific when it comes to this particular message.
I see the structure of the message is as below, and I know the signature type is RSA.
struct {
Signature signature;
} CertificateVerify;
The Signature type is defined in 7.4.3.
CertificateVerify.signature.md5_hash
MD5(handshake_messages);
CertificateVerify.signature.sha_hash
SHA(handshake_messages);
Based on what I've read it seems to be a concatenation of the sha1 hash and the md5 hash of all the previous messages sent and received (up to and excluding this one) and then RSA signed.
The piece that's got me a bit confused though is how to assemble the messages to hash them.
Does it use each fragment piece or does it use the re-assembled messages? Also, what parts of the messages does it use?
The RFC for TLS 1.1 says
starting at client hello up to but not including this message,
including the type and length fields of the handshake messages
but what about the DTLS specific parts like message_seq, fragment_offset, and fragment_length, do I include them?
UPDATE:
I have tried doing as the RFC for DTLS 1.2 shows (meaning keeping the messages fragmented, using all the handshake fields including DTLS specific fields, and not including the initial Client Hello or Hello Verify Request messages) but I am still receiving "Bad Signature". I do believe I'm signing properly, so it's my belief that I'm concatenating the data improperly to be signed.
For DTLS 1.2 it is defined. And reading RFC 4347, my impression is, RFC 6347 doesn't differ, it clarifies the calculations.
RFC 6347, 4.2.6. CertificateVerify and Finished Messages
RFC 4347, 4.2.6. Finished Messages
Related
Kindly clarify on the following queries about the OPC UA specification Part 4 Services,
From my understanding after the GetEndpoints Service messages, the client sends a OpenSecureChannel request to the server which means the request is signed or signed & encrypted according the security policy in the desired endpoint. I saw the following lines in the specification Part 4 Services, pg.no 33,
The OpenSecureChannel request and response Messages shall be signed
with the sender’s Certificate. These Messages shall always be
encrypted. If the transport layer does not provide encryption, then
these Messages shall be encrypted with the receiver’s Certificate.
In this it is mentioned that the messages shall always be encrypted. How does it rely on transport layer ?
And I also see another description in the OPC Unified Architecture Book by Wolfgang Mahnke, Stefan-Helmut Leitner, Matthias Damm as follows,
If the certificate is considered as trustworthy, then as the second
step an OpenSecureChannel request secured in accordance to the
Security Policy and the Security Mode is sent to the selected Session
Endpoint of the server. (Chapter 7, pg.no:213)
Here, it highlights that the message is secured in accordance to the Security Policy and Security Mode, so I request a clarification on the scenario if the security mode is sign?
Will the message be encrypted also?
In general, when the MessageSecurityMode is None then the SecurityPolicy ‘must’ be None? What is the exact usage of 'Invalid' MessageSecurityMode?
X509IdentityToken specification Part 4 Services section 7.35.4
This token shall always be accompanied by a signature in the
userTokenSignature parameter of ActivateSession if required by the
SecurityPolicy. The Server should specify a SecurityPolicy for the
UserTokenPolicy if the SecureChannel has a SecurityPolicy of None.
In the first line it is mentioned that ‘if required by the SecurityPolicy’, what is context of ‘if required’ when the userTokenSignature is a required field for X509IdentityToken ? In the second line it is mentioned that a explicit Security Policy is required if the SecureChannel has a SecurityPolicy of None, where ‘None’ means no certificates are exchanged and so X509IdentityToken cannot be used, referring to the following lines in the same specification (Section 5.6.3 ActivateSession, pg.no: 40)?
If the token is an X509IdentityToken then the proof is a signature
generated with private key associated with the Certificate. The data
to sign is created by appending the last serverNonce to the
serverCertificate specified in the CreateSession response.
For your kind information I use the specification released on November 2015 to study. Please clarify.
For the first question, the specification continues with "These requirements for OpenSecureChannel only apply if the securityPolicyUri is not None". So the answer is that a SecureChannel will both sign and encrypt the OpenSecureChannelRequest/Response for any MessageSecurityMode, except MessageSecurityMode.None.
For the second question, if MessageSecurityMode is None, then the Security policy is none. There is no usage of MessageSecurityMode.Invalid as far as I can find.
For the third question, if the securityPolicyUri is None, then no application certificates are exchanged. The client can provide a UserIdentity by a X509IdentityToken. The token consists of a X509Certificate and a signature. The signature is generated by appending the server nonce to the server certificate and signing with the user certificate's private key.
I have problems verifying a SAML-response I get form an ADFS Server. I get the response as an url like CALLBACK_URL?SAMLResponse=ENCODED_XML&Signature=SIGNATURE_VALUE&SigAlg=SIGNATURE_ALGORITHMwhile SIGNATURE_ALGORITHM is http://www.w3.org/2001/04/xmldsig-more#rsa-sha256. I managed to decode the response but I am not able to find a way to verify the response using the given signature.
My main problem is that the signature has a very unexpected format. Because of the given signature algorithm I expect the signature to have a length of 32 bytes but what I get when I base64-decode the signature is a string with length 256.
I expect that decoding the signature using base64 is not sufficient. Unfortunately I have not been able to find out what to do next so far. So my question is: What do I have to do to correctly decode the signature to be able to verify it?
I believe you're conflating a hash with a signature.
The signature takes the hash of the message as input and encrypts it with a key. In your case the SigAlg parameter indicates that the 32 byte hash of the SAML message is encrypted with (apparently) a 2048 bits RSA private key, possibly using PKCS#1 v1.5 padding as described in https://www.rfc-editor.org/rfc/rfc6931#section-2.3.2 resulting in a 256 byte signature that can be verified with the associated 2048 bits RSA public key of the sender.
Apart from that: I assume your referring to a SAML request rather than a SAML response since the latter must not be sent by using the HTTP redirect binding as written down in the Web Browser SSO Profile specification, page 16: https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf (top of the page):
Identity Provider issues to Service Provider In step 5, the identity provider issues a message to be delivered by
the user agent to the service provider. Either the HTTP POST, or HTTP
Artifact binding can be used to transfer the message to the service
provider through the user agent. The message may indicate an error, or
will include (at least) an authentication assertion. The HTTP Redirect
binding MUST NOT be used, as the response will typically exceed the
URL length permitted by most user agents.
Is there any way to verify the OpenSSL signature using only {signature,hashed message} pair, skipping the original file to be presented for verification?
I need to verify the signature with only {signature,hashed message} pair remotely so using the original file is cumbersome specially when its very large.
Is there any way to verify the OpenSSL signature using only hash value and without needing the original file?
Yes, but there are strings attached.
The scheme which requires the original message to be presented to the verifying function is a Signature Scheme with Appendix (SSA). A scheme like the old PKCS #1.0 signing is an example of it.
The scheme which does not require the original message is a Signature Scheme with Recovery (PSSR). In a PSSR, the encoded message is part of the signature and masked. A scheme like the new PKCS #2.0 PSSR signing is an example of it.
There are no schemes that take just a hash, as far as I know. You have to have the {message,signature} pair. Allowing the message to be disgorged from the signing or verification can be a security violation.
OpenSSL provides both of them, as does most other security libraries, like Botan, Crypto++, NSS, etc.
Also see RSA signature on TLS on Information Security Stack Exchange.
I have been trying to verify the signature with hash value remotely so using the original file is cumbersome specially when its very large.
That's the insecure thing signature schemes want to avoid....
Making a REST web server mainly based on large files uploads / downloads, I want to be able to check the file integrity. I believed that the proper way to do it was using Content-MD5 HTTP header [0] as proved useful by aws experience [1].
However, much to my dismay, I recently learned that it was (to be ?) deprecated [2].
The deprecation discussion did not give any workaround hint, so I am asking you :
Should I still decide to use a Content-MD5 HTTP header ?
Should I use an ETag with the same meaning (base64 encoding of the md5sum) ?
Should I use an ?md5sum=XXX parameter ?
Is there a better solution altogether ?
Thanks for your insights.
Best Regards,
B.
[0] https://webmasters.stackexchange.com/questions/2924/
[1] http://developer.amazonwebservices.com/connect/thread.jspa?threadID=22709
[2] http://trac.tools.ietf.org/wg/httpbis/trac/ticket/178
Add a custom header, called say X-YourService-Integrity. That makes it explicit that it's a system specific to your service, and allows you to use integrity check mechanisms other than MD5 in the future (for example, SHA1). It also avoids you having to "overload" existing mechanisms that are similar but not quite what you want.
https://www.ietf.org/rfc/rfc3230.txt
4.3.2 Digest
The Digest message header field provides a message digest of the
instance described by the message.
Digest = "Digest" ":" #(instance-digest)
The instance described by a message might be fully contained in the
message-body, partially-contained in the message-body, or not at all
contained in the message-body. The instance is specified by the
Request-URI and any cache-validator contained in the message.
A Digest header field MAY contain multiple instance-digest values.
This could be useful for responses expected to reside in caches
shared by users with different browsers, for example.
A recipient MAY ignore any or all of the instance-digests in a Digest
header field.
A sender MAY send an instance-digest using a digest-algorithm without
knowing whether the recipient supports the digest-algorithm, or even
knowing that the recipient will ignore it.
Examples:
Digest: md5=HUXZLQLMuI/KZ5KDcJPcOA==
Digest: SHA=thvDyvhfIqlvFe+A9MYgxAfm1q5=,unixsum=30637
Do not use Content-MD5: it has been deprecated because it leads to inconsistencies.
Use Digest with sha-256 or sha-512. We are updating RFC3230 to the latest HTTP specification (RFC7231) and added a lot of useful examples https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-digest-headers-02
Digest: sha-256=4REjxQ4yrqUVicfSKYNO/cF9zNj5ANbzgDZt3/h3Qxo=
There Want-Digest allows requesting a specific Digest header.
Eg. The client requests a digest, supporting sha-256 and sha-512. The server replies with sha-256
Request:
GET /items/123 HTTP/1.1
Want-Digest: sha-256, sha-512
Response:
HTTP/1.1 200 OK
Content-Type: application/json
Digest: sha-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
{"hello": "world"}
I'm trying to learn the XMPP spec (RFC 3920) by coding it in low-level Python. But I've been hung up for over an hour at step 4 of section 6.5, selecting an authentication mechanism. I'm sending: <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'/>, and getting: <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><incorrect-encoding/></failure> instead of a base64-encoded challenge.
The "incorrect-encoding" error is supposedly to be used for when I incorrectly base64-encode something, but there was no text to encode. I'm probably missing something really obvious. Anybody got a cluestick?
I'm using talk.google.com port 5222 as the server, if that matters. I doubt that it does; this is almost definitely due to my lack of understanding this section of the RFC. And the problem isn't likely my code, other than the way I'm sending this particular stanza, or it would be failing at the previous steps. But for what it's worth, here is the code I've got so far, and the complete log (transcript of the session). Thanks.
First off, RFC 6120 is often more clear than 3920. [updated to point to the RFC as released]
Since you're using SASL PLAIN (see RFC 4616), many servers expect you to send a SASL "initial response" in the auth element, consisting of:
base64(\x00 + utf8(saslprep(username)) + \x00 + utf8(saslprep(password)))
All together, then, your auth element needs to look like this:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
mechanism='PLAIN'>AGp1bGlldAByMG0zMG15cjBtMzA=</auth>
For the username "juliet" and the password "r0m30myr0m30".